VSCode LSP OnCompletion only suggests words that start with the letter "n" - vscode-extensions

I'm writing a VS Code Extension using the Language Server Protocol.
I'm having a strange issue with the word completion feature.
connection.onCompletion(
(_textDocumentPosition: TextDocumentPositionParams): CompletionItem[] => {
return [
{
label: 'foo',
kind: CompletionItemKind.Text,
data: 1
},
{
label: 'bar',
kind: CompletionItemKind.Text,
data: 2
},
{
label: 'nfoo',
kind: CompletionItemKind.Text,
data: 3
},
{
label: 'nbar',
kind: CompletionItemKind.Text,
data: 4
},
];
}
);
The LSP-Sample does this just fine. But in my implementation, this only prompts word completion in VS Code for the words starting with "n".
Even more confusing, if I install the Cloud Code extension from Google, all words start showing up as options.
See these GIFs:
without Cloud Code extension: https://gyazo.com/3ca97983e748910a0a93d2937950f8b5
with the Cloud Code extension: https://gyazo.com/73db98ce43583f4edec2a2af3817ec3a
Any ideas what this could be related to? And why another VS Code extension can interfere with my extension?

Related

Sanity CMS, using type "object" as reference

Is it not possible to use an object type as a reference in sanity? For example this is not working. When I go to the field nothing shows up. If I can't do this how can I access the indexPage objects that have been created under other documents?
export const indexPage = {
title: "Index Page",
name: "indexPage",
type: "object",
fields: [
{
title: "Subheading",
name: "subheading",
type: "array",
of: [{ type: 'block' }]
},
{
title: "Content",
name: "content",
type: "array",
of: [{ type: "block" }]
},
]
}
// in another file
export const coolPage = {
title: "Cool Page",
name: "coolPage",
type: "object",
fields: [
{
title: "Reference Index Page",
name: "refIndexPage",
type: "reference",
to: [{ type: 'indexPage' }]
}
]
}
References can only point to other documents; not to a specific part of a document. So to achieve this, indexPage would need to be a document.
I think modelling indexPage as a document would be a viable option in your case. You mentioned "indexPage objects that have been created under other documents". Instead of creating indexPage data inside a specific document, indexPage should be its own document type. Any other document can then connect to it via a reference. This approach should be really flexible for you.
Sanity Studio recently added support for "references in place", which makes this workflow even better. The studio now allows you to create a document to reference while you are editing the document that references it—without leaving the editor. You can see a demo here (no extra work on your part is needed here, it's handled automatically by Sanity Studio).
In summary: if you have a piece of data you'd like to share between multiple documents, model it as its own document type that is referenced by every document that is related.

How to set provider.apiGateway.shouldStartNameWithService in a serverless.ts file?

I am kicking off a new project with a new Serverless TypeScript monorepo! Used the aws-nodejs-typescript template, which gave a serverless.ts config file. After some weeks, I am now getting the nice warning below from Serverless on command line:
Serverless: Deprecation warning: Starting with next major version, API Gateway naming will be changed from “{stage}-{service}” to “{service}-{stage}”.
Set “provider.apiGateway.shouldStartNameWithService” to “true” to adapt to the new behavior now.
More Info: https://www.serverless.com/framework/docs/deprecations/#AWS_API_GATEWAY_NAME_STARTING_WITH_SERVICE
Ok! Looks great, and I like the new naming. And since it’s a new project, better to apply the new naming now, before we release anything. However, it looks like the TypeScript definitions are rather strict, and do not seem to allow for the new variable yet:
Loading failed with: TSError: ⨯ Unable to compile TypeScript:
serverless.ts(44,7): error TS2322: Type ‘{ minimumCompressionSize: number; shouldStartNameWithService: true; }’ is not assignable to type ‘ApiGateway’.
Object literal may only specify known properties, and ‘shouldStartNameWithService’ does not exist in type ‘ApiGateway’.
awsProvider.d.ts(51, 9): The expected type comes from property ‘apiGateway’ which is declared here on type ‘Provider’
Is there a way to set the new property without reverting everything to YAML, which would be somewhat painful at this point?
Update 1
Many thanks to #NexGen for the pointer! Here is a minimal serverless.ts (emphasis on the TS!) showing the solution.
import type { Serverless, ApiGateway } from 'serverless/aws';
const serverlessConfiguration: Serverless = {
service: {
name: 'foo',
},
frameworkVersion: '2',
custom: {
webpack: {
webpackConfig: './webpack.config.js',
packager: 'yarn',
includeModules: true,
},
alerts: {
stages: ['stage', 'prod'],
definitions: {
functionErrors: { treatMissingData: 'notBreaching' },
},
alarms: ['functionErrors'],
},
},
package: {
individually: true,
},
plugins: [
'serverless-webpack',
'serverless-jest-plugin',
'serverless-plugin-aws-alerts',
],
provider: {
name: 'aws',
runtime: 'nodejs12.x',
region: 'us-west-2',
stage: "${opt:stage, 'dev'}",
apiGateway: {
minimumCompressionSize: 1024,
shouldStartNameWithService: true,
} as ApiGateway,
environment: {
AWS_NODEJS_CONNECTION_REUSE_ENABLED: '1',
},
},
};
module.exports = serverlessConfiguration;
It is really simple to apply this change, all what you need to do is to add this to your serverless.yml file.
provider:
apiGateway:
shouldStartNameWithService: true
provider: {
name: 'aws',
runtime: 'nodejs12.x',
apiGateway: {
shouldStartNameWithService: true
} as ApiGateway,
stage: 'dev'
}

Nuxt.js preview on Facebook/Twitter doesn't work: 404 error

I have a site implemented with Nuxt.js and want to share the pages on Facebook, Twitter and WhatsApp. I have to use the metatags opengraph, so I've included them. When I try to share a page into a social network, I can't see the content of the metatags. I can't see the image either, the title and description.
In my case the metatags opengraph are well suited and filled in the page. I've read how to do it in several resources, so that's not the problem. They are located in the <head> tag.
But the problem is when you use the Facebook debugger tool to see your page preview, or the https://metatags.io/ tool. When I wrote the url of my page, a 404 is returned for these tools. For the same url in a browser, you can see properly the page how it is. If you inspect the page, you can see the meta tags.
I think the problem is Twitter or Facebook are doing a GET call to my url, but the result of this call, in my understanding, is a Nuxt.js pre-render page for being executed in the browser. In the browser the JS sources are executed at the moment of the page loading, so it can inject all the metatags and many other things. I think this is how Nuxt.js SSR is working. hydratation process?
So my point is how to send the complete HTML when a GET is done, or a workaround to show my preview page in Facebook or Twitter.
Btw, I have deployed my site in Netlify, I don't know if it matters.
My nuxtjs app is working on universal mode.
Any idea to resolve the problem with the crawlers and robots?
any prerender option?
I was researching and finally I've realized what was my real problem.
The main problem is I'm deploying the Nuxt app into netlify. This platform only allows you to deploy the Nuxt app as static resources (Static Generated Deployment, Pre-rendered). I mean, there are three ways to deploy a Nuxt app: universal, spa and universal as static mode (Static Generated Deployment, Pre-rendered). The third case is a special case, in which you have to create all the static resources as html pages in deploy time. For doing that you have to use the "npm run generate" command. In my case, I have some dynamic routes and I have to do some rest queries in order to achieve the data in every case. I don't have all the db rows to generate all the html pages at the build time. It's really expensive for me. So Nuxt at the end, for the case of dynamic routes, it's generating only a html page, but including the js part which is the client to the data. So when Facebook or google is calling to the url, they are getting the html with the js, but nothing of the data, because the js is only executed in the browser, and it's there, when the page gets the data via rest. So Facebook, Twitter of WhatsApp can't get the metadata of something that is missing. Additionally these services are getting a 404 http error code when they are calling to my urls, instead of a 200 http code. So it's impossible to share the url into these social services. The solution: or generate all the html pages for every resource in the build time (case 3) or moving to another provider as firebase in order to deploy as universal app (case 1) with an express server. I think I´ll move it to firebase to achieve a good SEO and social media features.
for the other hand I've changed my head method to accomplish with the open graph metadata:
head() {
return {
title: `${MyStringHandler.truncate(defaultTitle, 65)}`,
description: defaultDescription,
link: [
{
rel: 'canonical',
href: `${routePath}`
}
],
htmlAttrs: {
lang: `${language}`
},
meta: [
{
charset: 'utf-8'
},
{
hid: 'title',
name: 'title',
content: `${MyStringHandler.truncate(defaultTitle, 65)}`
},
{
hid: 'description',
name: 'description',
content: `${MyStringHandler.truncate(overviewDefault, 155)}`
},
{
hid: 'og:type',
property: 'og:type',
content: 'website'
},
{
hid: 'og:title',
property: 'og:title',
content: `${MyStringHandler.truncate(defaultTitle, 35)}`
},
{
hid: 'og:description',
property: 'og:description',
content: `${MyStringHandler.truncate(overviewDefault, 65)}`
},
{
hid: 'og:image',
property: 'og:image',
content: URLHelper.get2XURL(path) // the size has to be more 200px at least
},
{
hid: 'og:url',
property: 'og:url',
content: `www.mydomain.com${routePath}`
},
{
hid: 'og:site_name',
property: 'og:site_name',
content: `mydomain.com`
},
{
hid: 'og:locale',
property: 'og:locale',
content: `es`
},
{
hid: 'og:image:type',
property: 'og:image:type',
content: 'image/jpeg'
},
{
hid: 'twitter:card',
property: 'twitter:card',
content: `${MyStringHandler.truncate(overviewDefault, 65)}`
},
{
hid: 'twitter:site',
property: 'twitter:site',
content: 'mydomain'
},
{
hid: 'twitter:title',
name: 'twitter:title',
content: `${MyStringHandler.truncate(defaultTitle, 35)}`
},
{
hid: 'twitter:description',
name: 'twitter:description',
content: `${MyStringHandler.truncate(overviewDefault, 65)}`
},
{
hid: 'twitter:creator',
property: 'twitter:creator',
content: 'mydomain'
},
{
hid: 'twitter:image:src',
property: 'twitter:image:src',
content: URLHelper.getImageURL(path)
},
{
hid: 'twitter:domain',
property: 'twitter:domain',
content: 'mydomain.com'
},
{
hid: 'twitter:image',
name: 'twitter:image',
content: URLHelper.getImageURL(path)
},
{
hid: 'twitter:url',
name: 'twitter:url',
content: `www.mydomain.com${routePath}`
}
]
}
}
You can test the metadata into the next pages:
https://metatags.io
https://cards-dev.twitter.com/validator
https://developers.facebook.com/tools/debug/
update:
nuxt can generate your static resources in deploy time using npm run generate, and these resources are SEO-ables. The metatags are working well.

How to load plugin for s3 bucket with Nuxt?

I have a nuxt app with a few third party plugins, gsap, splitting.js, etc.. All of the plugins work fine as they should.
I have a simple-keyboard plugin loading in the same way as the others, it loads fine locally but after I run nuxt generate and upload my dist folder to the s3 bucket, the keyboard/plugin does not show up. There are also no errors in console. I'm not sure what is removing it?
I have created a file in the plugins directory like so:
plugins/simple-keyboard.js
In my nuxt.config.js file I have placed:
plugins: [
{ src: '~plugins/fastclick.js', ssr: false },
{ src: '~plugins/splitting.js', ssr: false },
{ src: '~plugins/simple-keyboard.js', ssr: false },
{ src: '~plugins/maskedinput.js', ssr: false }
],
Here is the contents of my plugins/simple-keyboard.js file:
import Keyboard from 'simple-keyboard';
import inputMask from "simple-keyboard-input-mask";
import 'simple-keyboard/build/css/index.css';
if(window.location.pathname == '/welcome') {
let keyboard = new Keyboard({
onChange: input => onChange(input),
onKeyPress: button => onKeyPress(button),
layout: {
default: ["1 2 3", "4 5 6", "7 8 9", "{C} 0 "],
shift: [" ABC DEF", "GHI JKL MNO", "PQRS TUV WXYZ"]
},
theme: "keyboard hg-theme-default hg-layout-numeric numeric-theme",
disableCaretPositioning: true,
inputMask: "(888) 888-8888",
modules: [inputMask],
syncInstanceInputs: true
})
let backspace = new Keyboard(".backspace", {
onChange: input => onChange(input),
onKeyPress: button => onKeyPress(button),
layout: {
default: ["{bksp}"]
},
mergeDisplay: true,
display: {
'{bksp}': ' '
},
theme: "hg-theme-default hg-layout-numeric numeric-theme",
syncInstanceInputs: true
})
function onChange(input) {
document.querySelector(".input").value = input;
}
function clearKeyboard() {
keyboard.clearInput();
document.querySelector(".input").value = '';
}
function onKeyPress(button) {
if (button === "{C}") clearKeyboard();
}
}
Locally everything works perfectly fine.
Even when I host it on a local PHP server and point to the dist file. everything runs fine.
When I run my build command and deploy the contents to my S3 bucket, everything works aside from the keyboard. It simply doesn't render.
I cannot figure out how to get the simple-keyboard plugin to properly render when deployed to S3.
I'm the creator of simple-keyboard, and just wanted to update this entry as it was resolved on a Discord chat.
The issue was in this line of code:
if(window.location.pathname == '/welcome') { ...
In the local environment, the pathname was indeed /welcome. However, once pushed to the server, the pathname became /welcome/ so the code never got to the part where the keyboard is instantiated.
Hope that helps anyone who encounters a similar issue.

How to parameterize ports in OpenShift JSON Project Template

I'm trying to create a custom project template in OpenShift Origin. The Service configuration specifically, looks like below:
{
"kind": "Service",
"apiVersion": "v1",
"metadata": {
"name": "${NAME}",
"annotations": {
"description": "Exposes and load balances the node.js application pods"
}
},
"spec": {
"ports": [
{
"name": "web",
"port": "${APPLICATION_PORT}",
"targetPort": "${APPLICATION_PORT}",
"protocol": "TCP"
}
],
"selector": {
"name": "${NAME}"
}
}
},
where, APPLICATION_PORT is supplied as a user parameter:
"parameters": [
{
"name": "APPLICATION_PORT",
"displayName": "Application Port",
"description": "The exposed port that will route to the node.js application",
"value": "8000"
},
When I try to use this template to create a project, I get the following error:
spec.ports[0].targetPort: Invalid value: "8000": must be an IANA_SVC_NAME (at most 15 characters, matching regex [a-z0-9]([a-z0-9-]*[a-z0-9])*...
I get a similar error in my DeploymentConfig as well, for the http ports in the liveness and readiness probes:
"readinessProbe": {
"timeoutSeconds": 3,
"initialDelaySeconds": 3,
"httpGet": {
"path": "/Info",
"port": "${APPLICATION_ADMIN_PORT}"
}
},
"livenessProbe": {
"timeoutSeconds": 3,
"initialDelaySeconds": 30,
"httpGet": {
"path": "/Info",
"port": "${APPLICATION_ADMIN_PORT}"
}
},
where, APPLICATION_ADMIN_PORT, again, is user-supplied.
Error:
spec.template.spec.containers[0].livenessProbe.httpGet.port: Invalid value: "8001": must be an IANA_SVC_NAME...
spec.template.spec.containers[0].readinessProbe.httpGet.port: Invalid value: "8001": must be an IANA_SVC_NAME...
I've been following https://blog.openshift.com/part-2-creating-a-template-a-technical-walkthrough/ to understand templates, and it, unfortunately, does not have any examples of ports being parameterized anywhere.
It almost seems as if strings are not allowed as the values of these ports. Is that the case? What's the right way to parameterize these values? Should I switch to YAML?
Versions:
OpenShift Master: v1.1.6-3-g9c5694f
Kubernetes Master: v1.2.0-36-g4a3f9c5
Edit 1: I tried the same configuration in YAML format, and got the same error. So, JSON vs YAML is not the issue.
Unfortunately it is not currently possible to parameterize non-string field values: https://docs.openshift.org/latest/dev_guide/templates.html#writing-parameters
" Parameters can be referenced by placing values in the form "${PARAMETER_NAME}" in place of any string field in the template."
Templates are in the process of being upstreamed to Kubernetes and this limitation is being addressed there:
https://github.com/kubernetes/kubernetes/blob/master/docs/proposals/templates.md
The proposal is being implemented in PRs 25622 and 25293 in the kubernetes repo.
edit:
Templates now support non-string parameters as documented here: https://docs.openshift.org/latest/dev_guide/templates.html#writing-parameters
I don't know if this option was available in 2016 when this post was added but now you can use ${{PARAMETER_NAME}} to parameterize non-string field values.
spec:
externalTrafficPolicy: Cluster
ports:
- name: ${NAME}-port
port: ${{PORT_PARAMETER}}
protocol: TCP
targetPort: ${{PORT_PARAMETER}}
sessionAffinity: None
This may a be a bad practice but I'm using sed to substitute int parameters:
cat template.yaml | sed -e 's/PORT/8080/g' > proxy-template-subst.yaml
Template:
apiVersion: template.openshift.io/v1
kind: Template
objects:
- apiVersion: v1
kind: Service
metadata:
name: ${NAME}
namespace: ${NAMESPACE}
spec:
externalTrafficPolicy: Cluster
ports:
- name: ${NAME}-port
port: PORT
protocol: TCP
targetPort: PORT
sessionAffinity: None
type: NodePort
status:
loadBalancer: {}
parameters:
- description: Desired service name
name: NAME
required: true
value: need_real_value_here
- description: IP adress
name: IP
required: true
value: need_real_value_here
- description: namespace where to deploy
name: NAMESPACE
required: true
value: need_real_value_here