Skip to content

Commit

Permalink
feat: annotation relevant lsp package (#535)
Browse files Browse the repository at this point in the history
* feat: new annotation lsp package

* feat: commit just to trigger rebuild

* fix: yarn lock file fix

* fix: yarn install fix

* feat: lsp diagnostics enhancement and coverage fix

* fix: coverage fix

* fix: failing linter tests and other improvements

* fix: diagnostics improvement, other corrections

* fix: webpack bundling for module loader

* feat: diagnostics improvement, partial refactoring

* fix: code clean up

* fix: work on pr comments

* feat: i18n support

* feat: manual testcases

* fix: work on PR comments

* fix: pr comments

* fix: fe module marked as private

BREAKING CHANGE: introduce context by pr #523

Co-authored-by: Klaus Keller <[email protected]>
  • Loading branch information
vadson71 and Klaus-Keller authored Jan 25, 2023
1 parent 8060f6c commit 6b35d43
Show file tree
Hide file tree
Showing 80 changed files with 14,964 additions and 7,946 deletions.
22 changes: 22 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,28 @@
"internalConsoleOptions": "neverOpen",
"disableOptimisticBPs": true,
"cwd": "${workspaceFolder}/packages/context"
},
{
"type": "node",
"request": "launch",
"name": "fe: run current file",
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"args": ["${fileBasenameNoExtension}"],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"disableOptimisticBPs": true,
"cwd": "${workspaceFolder}/packages/fe"
},
{
"type": "node",
"request": "launch",
"name": "semantic-model: run current file",
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
"args": ["${fileBasenameNoExtension}"],
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"disableOptimisticBPs": true,
"cwd": "${workspaceFolder}/packages/semantic-model"
}
]
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"@types/deep-equal-in-any-order": "1.0.1",
"@types/fs-extra": "9.0.11",
"@types/klaw-sync": "6.0.0",
"@types/lodash": "4.14.168",
"@types/lodash": "4.14.166",
"@types/mocha": "9.1.1",
"@types/rimraf": "3.0.0",
"@types/sinon": "9.0.10",
Expand All @@ -58,6 +58,7 @@
"fs-extra": "10.1.0",
"glob": "7.1.6",
"husky": "8.0.1",
"i18next": "19.0.2",
"klaw-sync": "6.0.0",
"lerna": "6.0.3",
"lint-staged": "10.5.3",
Expand Down
1 change: 1 addition & 0 deletions packages/context/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export {
reactOnXmlFileChange,
reactOnPackageJson,
cache,
DEFAULT_I18N_NAMESPACE,
} from "./src/api";

export type {
Expand Down
2 changes: 1 addition & 1 deletion packages/context/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"devDependencies": {
"@sap-ux/vocabularies-types": "0.6.8",
"@types/js-yaml": "4.0.5",
"@types/lodash": "4.14.166",
"@types/lodash": "4.14.168",
"@types/node-fetch": "2.5.10",
"@types/semver": "7.3.12",
"@ui5-language-assistant/semantic-model-types": "3.3.1",
Expand Down
2 changes: 2 additions & 0 deletions packages/context/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,5 @@ export async function getContext(
const customViewId = await getCustomViewId(documentPath);
return { manifestDetails, yamlDetails, ui5Model, services, customViewId };
}

export const DEFAULT_I18N_NAMESPACE = "translation";
47 changes: 37 additions & 10 deletions packages/context/src/fetch.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,38 @@
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const importDynamic = new Function("modulePath", "return import(modulePath)");
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const nodeFetch = async (...args: any[]) => {
const module = await importDynamic("node-fetch");
return module.default(...args);
};
import { RequestInfo, RequestInit, Response } from "node-fetch";
import HttpsProxyAgent from "https-proxy-agent";
import { getProxyForUrl } from "proxy-from-env";
import HttpsProxyAgent from "https-proxy-agent";
import { RequestInfo, RequestInit, Response } from "node-fetch";

export type FetcherType = (
url: RequestInfo,
init?: RequestInit | undefined
) => Promise<Response>;

/**
* Promise which prepares dynamic node fetcher function and holds it within once resolved
*/
const nodeFetchCached = new Promise<FetcherType>((done, reject) => {
(async () => {
let nodeFetch: FetcherType;
try {
// this should work when bundled
nodeFetch = (await import("node-fetch")).default;
} catch (e) {
// trying to load dynamically
const importDynamic = new Function(
"modulePath",
"return import(modulePath)"
);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
nodeFetch = async (...args: any[]) => {
const module = await importDynamic("node-fetch");
return module.default(...args);
};
}
return nodeFetch;
})()
.then((result) => done(result))
.catch((error) => reject(error));
});

/**
* Wrapper for the node-fetch API to utilize a proxy if needed
Expand All @@ -28,6 +53,8 @@ export default async function fetch(
agent: HttpsProxyAgent(proxy),
});
}
// call the node-fetch API

// call the cached node-fetch API
const nodeFetch = await nodeFetchCached;
return nodeFetch(url, init);
}
4 changes: 4 additions & 0 deletions packages/fe/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Change Log

All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
4 changes: 4 additions & 0 deletions packages/fe/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Contribution Guide

This package does not have any unique development flows.
Please see the top level [Contribution Guide](../../CONTRIBUTING.md).
32 changes: 32 additions & 0 deletions packages/fe/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[![npm (scoped)](https://img.shields.io/npm/v/@ui5-language-assistant/context.svg)](https://www.npmjs.com/package/@ui5-language-assistant/fe)

# @ui5-language-assistant/fe

UI5 language assistant extension with LSP for annotation-relevant building blocks

## Installation

With npm:

- `npm install @ui5-language-assistant/fe`

With Yarn:

- `yarn add @ui5-language-assistant/fe`

## Usage

This package only exposes programmatic APIs, import the package and use the exported APIs
defined in [api.d.ts](./api.d.ts).

## Support

Please open [issues](https://github.com/SAP/ui5-language-assistant/issues) on github.

## Contributing

See [CONTRIBUTING.md](./CONTRIBUTING.md).

## Licensing

Copyright 2022 SAP SE. Please see our [LICENSE](../../LICENSE) for copyright and license information. Detailed information including third-party components and their licensing/copyright information is available [via the REUSE tool](https://api.reuse.software/info/github.com/SAP/ui5-language-assistant).
34 changes: 34 additions & 0 deletions packages/fe/api.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type {
BaseUI5XMLViewIssue,
UI5ValidatorsConfig,
} from "@ui5-language-assistant/xml-views-validation";
import type { Context } from "@ui5-language-assistant/context";
import type {
TextDocumentPositionParams,
CompletionItem,
} from "vscode-languageserver-protocol";
import type { CstNode, IToken } from "chevrotain";
import type { XMLDocument } from "@xml-tools/ast";
import type { TextDocument } from "vscode-languageserver-textdocument";
import type { Settings } from "@ui5-language-assistant/settings";
import type { AnnotationIssue } from "./src/types/issues";

export type { AnnotationIssue } from "./src/types/issues";

export declare const defaultValidators: UI5ValidatorsConfig<AnnotationIssue>;

export function getCompletionItems(opts: {
context: Context;
textDocumentPosition: TextDocumentPositionParams;
document: TextDocument;
documentSettings: Settings;
cst: CstNode;
tokenVector: IToken[];
ast: XMLDocument;
}): CompletionItem[];

export function isAnnotationIssue<T extends BaseUI5XMLViewIssue>(
issue: AnnotationIssue | T
): issue is AnnotationIssue;

export function initI18n(i18nInstance: i18n): void;
47 changes: 47 additions & 0 deletions packages/fe/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"name": "@ui5-language-assistant/fe",
"version": "3.3.1",
"description": "UI5 LSP server extension for annotation relevant building blocks",
"keywords": [],
"files": [
".reuse",
"LICENSES",
"lib/src",
"api.d.ts",
"src"
],
"main": "lib/src/api.js",
"repository": "https://github.com/sap/ui5-language-assistant/",
"license": "Apache-2.0",
"typings": "./api.d.ts",
"dependencies": {
"lodash": "4.17.21",
"@ui5-language-assistant/logic-utils": "3.3.1",
"@ui5-language-assistant/context": "3.3.1",
"@ui5-language-assistant/xml-views-completion": "3.3.1",
"@ui5-language-assistant/xml-views-validation": "3.3.1",
"deep-freeze-strict": "1.1.1"
},
"devDependencies": {
"@sap-ux/vocabularies-types": "0.6.8",
"@types/lodash": "4.14.168",
"@ui5-language-assistant/semantic-model-types": "3.3.1",
"@ui5-language-assistant/test-framework": "3.3.1",
"@ui5-language-assistant/test-utils": "3.3.1",
"@xml-tools/ast": "5.0.0",
"@xml-tools/parser": "1.0.7",
"vscode-languageserver-types": "3.17.2",
"vscode-languageserver-protocol": "3.17.2"
},
"scripts": {
"ci": "npm-run-all clean compile lint coverage",
"clean": "rimraf ./lib ./coverage ./nyc_output",
"compile": "yarn run clean && tsc -p .",
"compile:watch": "tsc -p . --watch",
"lint": "eslint . --ext .ts --max-warnings=0 --ignore-path=../../.gitignore",
"test": "mocha",
"coverage": "nyc mocha",
"format:fix": "prettier --write \"**/*.@(js|ts|json|md)\" --ignore-path=.gitignore"
},
"private": true
}
15 changes: 15 additions & 0 deletions packages/fe/src/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { UI5XMLViewIssue } from "@ui5-language-assistant/xml-views-validation";
import type { AnnotationIssue } from "./types";
import { ANNOTATION_ISSUE_TYPE } from "./types";

export { defaultValidators } from "./services/diagnostics/validators";
export type { AnnotationIssue } from "./types";

export function isAnnotationIssue(
issue: AnnotationIssue | UI5XMLViewIssue
): issue is AnnotationIssue {
return (issue as AnnotationIssue).issueType === ANNOTATION_ISSUE_TYPE;
}

export { getCompletionItems } from "./services/completion";
export { initI18n } from "./i18n";
11 changes: 11 additions & 0 deletions packages/fe/src/i18n.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { i18n } from "i18next";
import { DEFAULT_I18N_NAMESPACE } from "@ui5-language-assistant/context";
import i18nEn from "./i18n/i18n.json";

export function initI18n(i18nInstance: i18n): void {
i18nInstance.addResourceBundle(
i18nInstance.language,
DEFAULT_I18N_NAMESPACE,
i18nEn
);
}
31 changes: 31 additions & 0 deletions packages/fe/src/i18n/i18n.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"CONTEXT_PATH_IS_USUALLY_DEFINED_FOR_PAGE_DIFFERENT_BINDING": "Context path for {{control}} is usually defined if binding for the object is different than that of the page",
"CONTEXT_PATH_IS_MANDATORY": "contextPath value cannot be empty. Enter value or remove contextPath property",
"INVALID_CONTEXT_PATH_VALUE": "Invalid contextPath value: \"{{value}}\". Absolute path is expected",
"INCOMPLETE_CONTEXT_PATH_LEADS_TO_ENTITY_CONTAINER": "Path is incomplete. It leads to entity container",
"INCOMPLETE_CONTEXT_PATH_TRIGGER_CODE_COMPLETION": "Path is incomplete. Trigger code completion to choose next available path segment",
"UNKNOWN_CONTEXT_PATH": "Unknown context path: \"{{value}}\"",
"INVALID_CONTEXT_PATH_MULTIPLE_1_TO_MANY": "Invalid contextPath value. Multiple 1:many association segments not allowed",
"CONTEXT_PATH_LEADS_TO_WRONG_TARGET": "Invalid contextPath value. The path leads to {{actualType}}, but expected types are: {{expectedTypes}}",
"CONTEXT_PATH_DOES_NOT_LEAD_TO_ANNOTATIONS": "Invalid contextPath value. It does not lead to any annotations of the expected type",
"INVALID_CONTEXT_PATH_TRIGGER_CODE_COMPLETION": "Invalid contextPath value. Trigger code completion to choose one of valid targets if some are available",

"ANNOTATION_PATH_IS_MANDATORY": "Annotation path value cannot be empty",
"PATH_VALUE_MUST_END_WITH_A_TERM": "Path value must end with annotation term. Use code completion to select annotation path",
"ABSOLUTE_ANNOTATION_PATH_NOT_ALLOWED": "Absolute annotation paths not allowed in metaPath. Use contextPath attribute to change path context",
"NAVIGATION_SEGMENTS_NOT_ALLOWED_WHEN_CONTEXT_PATH_EXISTS": "Navigation segments not allowed when contextPath is provided",
"UNKNOWN_ANNOTATION_PATH": "Unknown annotation path: \"{{value}}\"",
"INVALID_ANNOTATION_TERM_TRIGGER_CODE_COMPLETION": "Invalid annotation term: \"{{value}}\". Trigger code completion to choose one of allowed annotations",
"INVALID_ANNOTATION_TERM_THERE_ARE_NO_SUITABLE_ANNOTATIONS": "Invalid annotation term: \"{{value}}\". There are no annotations in the project that are suitable for the current context",
"VIEW_ENTITY_SET_IS_NOT_FOUND": "Entity Set \"{{value}}\" specified in manifest for the current view is not found. Attribute value completion and diagnostics are disabled",

"META_PATH_IS_MANDATORY": "Property path value cannot be empty",
"PROPERTY_META_PATH_LEADS_TO_WRONG_TARGET": "Invalid path value. The path leads to {{actualType}}, but expected type is Edm.Property",
"UNKNOWN_PATH": "Unknown path: \"{{value}}\"",
"INVALID_PROPERTY_PATH_MULTIPLE_1_TO_MANY": "Invalid property path value. Multiple 1:many association segments not allowed",

"ENTITY_SET_IS_MISSING_IN_MANIFEST": "EntitySet for the current view is missing in application manifest. Attribute value completion and diagnostics are disabled",
"FILTER_BAR_ID_DOES_NOT_EXIST_TRIGGER_CODE_COMPLETION": "FilterBar with id \"{{value}}\" does not exist. Trigger code completion to choose one of existing FilterBar ids",
"FILTER_BAR_ID_DOES_NOT_EXIST": "FilterBar with id \"{{value}}\" does not exist",
"FILTER_BAR_ID_IS_EMPTY_TRIGGER_CODE_COMPLETION": "Trigger code completion to choose one of existing FilterBar ids"
}
1 change: 1 addition & 0 deletions packages/fe/src/services/completion/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { getCompletionItems } from "./utils";
Loading

0 comments on commit 6b35d43

Please sign in to comment.