Merge remote-tracking branch 'powerbi/master' into release-1.10.1
This commit is contained in:
Родитель
ca243d8f61
Коммит
fbb9310643
|
@ -0,0 +1,4 @@
|
|||
/node_modules/*
|
||||
demo/*
|
||||
/**/*.js
|
||||
dist/*
|
|
@ -0,0 +1,236 @@
|
|||
module.exports = {
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:@typescript-eslint/recommended-requiring-type-checking"
|
||||
],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"parserOptions": {
|
||||
"project": "webpack.test.tsconfig.json",
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": [
|
||||
"eslint-plugin-jsdoc",
|
||||
"eslint-plugin-prefer-arrow",
|
||||
"eslint-plugin-import",
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/adjacent-overload-signatures": "warn",
|
||||
"@typescript-eslint/array-type": "off",
|
||||
"@typescript-eslint/await-thenable": "warn",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/ban-types": [
|
||||
"warn",
|
||||
{
|
||||
"types": {
|
||||
"Object": {
|
||||
"message": "Avoid using the `Object` type. Did you mean `object`?"
|
||||
},
|
||||
"Function": false,
|
||||
"object": false,
|
||||
"Boolean": {
|
||||
"message": "Avoid using the `Boolean` type. Did you mean `boolean`?"
|
||||
},
|
||||
"Number": {
|
||||
"message": "Avoid using the `Number` type. Did you mean `number`?"
|
||||
},
|
||||
"String": {
|
||||
"message": "Avoid using the `String` type. Did you mean `string`?"
|
||||
},
|
||||
"Symbol": {
|
||||
"message": "Avoid using the `Symbol` type. Did you mean `symbol`?"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/consistent-type-definitions": "off",
|
||||
"@typescript-eslint/dot-notation": "off",
|
||||
"@typescript-eslint/explicit-member-accessibility": [
|
||||
"off",
|
||||
{
|
||||
"accessibility": "explicit"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/explicit-module-boundary-types": [
|
||||
"warn",
|
||||
{ "allowArgumentsExplicitlyTypedAsAny": true }
|
||||
],
|
||||
"@typescript-eslint/indent": [
|
||||
"warn",
|
||||
4,
|
||||
{
|
||||
"SwitchCase": 1,
|
||||
"FunctionDeclaration": {
|
||||
"parameters": "first"
|
||||
},
|
||||
"FunctionExpression": {
|
||||
"parameters": "first"
|
||||
}
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/member-delimiter-style": [
|
||||
"warn",
|
||||
{
|
||||
"multiline": {
|
||||
"delimiter": "semi",
|
||||
"requireLast": true
|
||||
},
|
||||
"singleline": {
|
||||
"delimiter": "semi",
|
||||
"requireLast": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/explicit-function-return-type": [
|
||||
"error",
|
||||
{
|
||||
"allowExpressions": true,
|
||||
"allowDirectConstAssertionInArrowFunctions": true
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/member-ordering": "off",
|
||||
"@typescript-eslint/naming-convention": "off",
|
||||
"@typescript-eslint/no-array-constructor": "warn",
|
||||
"@typescript-eslint/no-empty-function": "warn",
|
||||
"@typescript-eslint/no-empty-interface": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-extra-non-null-assertion": "warn",
|
||||
"@typescript-eslint/no-extra-semi": "warn",
|
||||
"@typescript-eslint/no-floating-promises": "off",
|
||||
"@typescript-eslint/no-for-in-array": "warn",
|
||||
"@typescript-eslint/no-implied-eval": "warn",
|
||||
"@typescript-eslint/no-inferrable-types": "off",
|
||||
"@typescript-eslint/no-misused-new": "warn",
|
||||
"@typescript-eslint/no-misused-promises": "off",
|
||||
"@typescript-eslint/no-namespace": "warn",
|
||||
"@typescript-eslint/no-non-null-asserted-optional-chain": "warn",
|
||||
"@typescript-eslint/no-non-null-assertion": "warn",
|
||||
"@typescript-eslint/no-parameter-properties": "off",
|
||||
"@typescript-eslint/no-this-alias": "warn",
|
||||
"@typescript-eslint/no-unnecessary-type-assertion": "warn",
|
||||
"@typescript-eslint/no-unsafe-assignment": "off",
|
||||
"@typescript-eslint/no-unsafe-call": "off",
|
||||
"@typescript-eslint/no-unsafe-member-access": "off",
|
||||
"@typescript-eslint/no-unsafe-return": "off",
|
||||
"@typescript-eslint/no-unused-expressions": "warn",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"warn",
|
||||
{
|
||||
"args": "after-used", "argsIgnorePattern": "^_"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-use-before-define": "off",
|
||||
"@typescript-eslint/no-var-requires": "off",
|
||||
"@typescript-eslint/prefer-as-const": "warn",
|
||||
"@typescript-eslint/prefer-for-of": "warn",
|
||||
"@typescript-eslint/prefer-namespace-keyword": "warn",
|
||||
"@typescript-eslint/prefer-regexp-exec": "off",
|
||||
"@typescript-eslint/quotes": [
|
||||
"off",
|
||||
{
|
||||
"avoidEscape": true
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/require-await": "warn",
|
||||
"@typescript-eslint/restrict-plus-operands": "warn",
|
||||
"@typescript-eslint/restrict-template-expressions": "off",
|
||||
"@typescript-eslint/semi": [
|
||||
"error",
|
||||
],
|
||||
"@typescript-eslint/triple-slash-reference": [
|
||||
"warn",
|
||||
{
|
||||
"path": "always",
|
||||
"types": "prefer-import",
|
||||
"lib": "always"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/type-annotation-spacing": "warn",
|
||||
"@typescript-eslint/unbound-method": "off",
|
||||
"@typescript-eslint/unified-signatures": "warn",
|
||||
"arrow-parens": "off",
|
||||
"brace-style": [
|
||||
"off",
|
||||
"1tbs"
|
||||
],
|
||||
"comma-dangle": "off",
|
||||
"complexity": "off",
|
||||
"constructor-super": "warn",
|
||||
"eol-last": "warn",
|
||||
"eqeqeq": [
|
||||
"warn",
|
||||
"smart"
|
||||
],
|
||||
"guard-for-in": "warn",
|
||||
"id-blacklist": [
|
||||
"warn",
|
||||
"any",
|
||||
"Number",
|
||||
"number",
|
||||
"String",
|
||||
"string",
|
||||
"Boolean",
|
||||
"boolean",
|
||||
"Undefined",
|
||||
],
|
||||
"id-match": "warn",
|
||||
"import/order": "off",
|
||||
"jsdoc/check-alignment": "warn",
|
||||
"jsdoc/check-indentation": "warn",
|
||||
"jsdoc/newline-after-description": "warn",
|
||||
"max-classes-per-file": "off",
|
||||
"max-len": "off",
|
||||
"new-parens": "warn",
|
||||
"no-array-constructor": "off",
|
||||
"no-caller": "warn",
|
||||
"no-cond-assign": "warn",
|
||||
"no-console": "off",
|
||||
"no-debugger": "warn",
|
||||
"no-empty": "warn",
|
||||
"no-empty-function": "off",
|
||||
"no-eval": "warn",
|
||||
"no-extra-semi": "off",
|
||||
"no-fallthrough": "off",
|
||||
"no-implied-eval": "off",
|
||||
"no-invalid-this": "off",
|
||||
"no-multiple-empty-lines": [
|
||||
"error",
|
||||
{ "max": 1 }
|
||||
],
|
||||
"no-new-wrappers": "warn",
|
||||
"no-shadow": "off",
|
||||
"no-trailing-spaces": "warn",
|
||||
"no-undef-init": "warn",
|
||||
"no-underscore-dangle": "off",
|
||||
"no-unsafe-finally": "warn",
|
||||
"no-unused-labels": "warn",
|
||||
"no-var": "warn",
|
||||
"object-shorthand": ["warn", "never"],
|
||||
"one-var": "off",
|
||||
"prefer-const": "off",
|
||||
"prefer-rest-params": "warn",
|
||||
"quote-props": [
|
||||
"warn",
|
||||
"consistent-as-needed"
|
||||
],
|
||||
"radix": "warn",
|
||||
"require-await": "off",
|
||||
"sort-keys": "off",
|
||||
"space-before-function-paren": "off",
|
||||
"spaced-comment": [
|
||||
"warn",
|
||||
"always",
|
||||
{
|
||||
"markers": [
|
||||
"/"
|
||||
]
|
||||
}
|
||||
],
|
||||
"use-isnan": "warn",
|
||||
"valid-typeof": "off"
|
||||
}
|
||||
};
|
|
@ -6,6 +6,4 @@ docs
|
|||
tmp
|
||||
.publish
|
||||
npm-debug.log*
|
||||
package-lock.json
|
||||
.vscode
|
||||
owners.txt
|
||||
|
|
30
gulpfile.js
30
gulpfile.js
|
@ -3,7 +3,7 @@ var del = require('del'),
|
|||
header = require('gulp-header'),
|
||||
help = require('gulp-help-four'),
|
||||
rename = require('gulp-rename'),
|
||||
tslint = require('gulp-tslint'),
|
||||
eslint = require('gulp-eslint'),
|
||||
typedoc = require("gulp-typedoc"),
|
||||
uglify = require('gulp-uglify'),
|
||||
karma = require('karma'),
|
||||
|
@ -26,7 +26,7 @@ var banner = webpackBanner + "\n";
|
|||
|
||||
gulp.task('build', 'Build for release', function (done) {
|
||||
return runSequence(
|
||||
'tslint:build',
|
||||
'lint:ts',
|
||||
'clean:dist',
|
||||
'compile:ts',
|
||||
'min',
|
||||
|
@ -38,7 +38,7 @@ gulp.task('build', 'Build for release', function (done) {
|
|||
|
||||
gulp.task('test', 'Runs all tests', function (done) {
|
||||
return runSequence(
|
||||
'tslint:test',
|
||||
'lint:ts',
|
||||
'clean:tmp',
|
||||
'compile:spec',
|
||||
'test:js',
|
||||
|
@ -139,23 +139,15 @@ gulp.task('test:js', 'Run spec tests', function (done) {
|
|||
|
||||
if (argv.chrome) {
|
||||
return watch(["src/**/*.ts", "test/**/*.ts"], function () {
|
||||
runSequence( 'tslint:test', 'clean:tmp', 'compile:spec');
|
||||
runSequence( 'lint:ts', 'clean:tmp', 'compile:spec');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
gulp.task('tslint:build', 'Run TSLint on src', function () {
|
||||
return gulp.src(["src/**/*.ts"])
|
||||
.pipe(tslint({
|
||||
formatter: "verbose"
|
||||
}))
|
||||
.pipe(tslint.report());
|
||||
});
|
||||
|
||||
gulp.task('tslint:test', 'Run TSLint on src and tests', function () {
|
||||
return gulp.src(["src/**/*.ts", "test/**/*.ts"])
|
||||
.pipe(tslint({
|
||||
formatter: "verbose"
|
||||
}))
|
||||
.pipe(tslint.report());
|
||||
});
|
||||
gulp.task('lint:ts', 'Lints all TypeScript', function () {
|
||||
return gulp.src(['./src/**/*.ts', './test/**/*.ts'])
|
||||
.pipe(eslint({
|
||||
formatter: "verbose"
|
||||
}))
|
||||
.pipe(eslint.format());
|
||||
});
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
31
package.json
31
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "powerbi-models",
|
||||
"version": "1.9.8",
|
||||
"version": "1.10.3",
|
||||
"description": "Contains JavaScript & TypeScript object models for Microsoft Power BI JavaScript SDK. For each model there is a TypeScript interface, and a validation function to ensure and object is valid.",
|
||||
"main": "dist/models.js",
|
||||
"typings": "dist/models.d.ts",
|
||||
|
@ -8,6 +8,7 @@
|
|||
"test": "test"
|
||||
},
|
||||
"scripts": {
|
||||
"preinstall": "npx force-resolutions",
|
||||
"build": "gulp build",
|
||||
"test": "gulp test",
|
||||
"gulp": "gulp",
|
||||
|
@ -20,6 +21,11 @@
|
|||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/powerbi-models"
|
||||
},
|
||||
"resolutions": {
|
||||
"glob-parent": "^6.0.2",
|
||||
"micromatch": "^4.0.5",
|
||||
"braces": "^3.0.2"
|
||||
},
|
||||
"keywords": [
|
||||
"Microsoft",
|
||||
"PowerBI",
|
||||
|
@ -32,19 +38,25 @@
|
|||
"devDependencies": {
|
||||
"@types/jasmine": "^3.5.5",
|
||||
"@types/karma-jasmine": "0.0.31",
|
||||
"@typescript-eslint/eslint-plugin": "^4.7.0",
|
||||
"@typescript-eslint/parser": "^4.7.0",
|
||||
"del": "^2.2.1",
|
||||
"eslint": "^7.13.0",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-jsdoc": "^30.7.7",
|
||||
"eslint-plugin-prefer-arrow": "^1.2.2",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-eslint": "^6.0.0",
|
||||
"gulp-header": "^1.8.7",
|
||||
"gulp-help-four": "^0.2.3",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-tslint": "^7.1.0",
|
||||
"gulp-typedoc": "^2.0.0",
|
||||
"gulp-uglify": "^1.5.4",
|
||||
"gulp-uglify": "^3.0.2",
|
||||
"gulp-watch": "^5.0.1",
|
||||
"gulp4-run-sequence": "^1.0.0",
|
||||
"jasmine-core": "^2.4.1",
|
||||
"json-loader": "^0.5.4",
|
||||
"karma": "^4.4.1",
|
||||
"karma": "^6.3.17",
|
||||
"karma-chrome-launcher": "^3.1.0",
|
||||
"karma-coverage": "^2.0.1",
|
||||
"karma-jasmine": "^0.3.8",
|
||||
|
@ -53,12 +65,11 @@
|
|||
"karma-spec-reporter": "0.0.32",
|
||||
"phantomjs-prebuilt": "^2.1.7",
|
||||
"ts-loader": "^6.2.1",
|
||||
"tslint": "^5.20.0",
|
||||
"typedoc": "^0.15.0",
|
||||
"typescript": "^3.8.2",
|
||||
"webpack": "^4.42.0",
|
||||
"webpack-stream": "^5.2.1",
|
||||
"yargs": "^4.7.1"
|
||||
"typedoc": "^0.22.14",
|
||||
"typescript": "~4.6.0",
|
||||
"webpack": "^5.71.0",
|
||||
"webpack-stream": "^7.0.0",
|
||||
"yargs": "^17.4.1"
|
||||
},
|
||||
"publishConfig": {},
|
||||
"dependencies": {}
|
||||
|
|
|
@ -60,8 +60,8 @@ export interface ICustomPageSize extends IPageSize {
|
|||
height?: number;
|
||||
}
|
||||
|
||||
export type PagesLayout = { [key: string]: IPageLayout; };
|
||||
export type VisualsLayout = { [key: string]: IVisualLayout; };
|
||||
export type PagesLayout = { [key: string]: IPageLayout };
|
||||
export type VisualsLayout = { [key: string]: IVisualLayout };
|
||||
|
||||
export interface IPageLayout {
|
||||
defaultLayout?: IVisualLayout;
|
||||
|
@ -312,6 +312,10 @@ export interface IBaseTarget {
|
|||
$schema?: string;
|
||||
}
|
||||
|
||||
export interface IPercentOfGrandTotalTarget {
|
||||
percentOfGrandTotal?: boolean;
|
||||
}
|
||||
|
||||
export interface IColumnTarget extends IBaseTarget {
|
||||
column: string;
|
||||
}
|
||||
|
@ -331,11 +335,11 @@ export interface IHierarchyLevelTarget extends IBaseTarget {
|
|||
|
||||
export interface INotSupportedTarget extends IBaseTarget { }
|
||||
|
||||
export interface IMeasureTarget extends IBaseTarget {
|
||||
export interface IMeasureTarget extends IBaseTarget, IPercentOfGrandTotalTarget {
|
||||
measure: string;
|
||||
}
|
||||
|
||||
export interface IAggregationTarget {
|
||||
export interface IAggregationTarget extends IPercentOfGrandTotalTarget {
|
||||
aggregationFunction: string;
|
||||
}
|
||||
|
||||
|
@ -725,6 +729,7 @@ export class BasicFilter extends Filter {
|
|||
* new BasicFilter('a', 'b', [1,2]);
|
||||
*/
|
||||
if (Array.isArray(values[0])) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||
this.values = (values[0] as (string | number | boolean)[]);
|
||||
}
|
||||
else {
|
||||
|
@ -859,6 +864,7 @@ export class AdvancedFilter extends Filter {
|
|||
* new AdvancedFilter('a', 'b', "And", [{ value: 1, operator: "Equals" }, { value: 2, operator: "IsGreaterThan" }]);
|
||||
*/
|
||||
if (Array.isArray(conditions[0])) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||
extractedConditions = (conditions[0] as IAdvancedFilterCondition[]);
|
||||
}
|
||||
else {
|
||||
|
@ -958,6 +964,10 @@ export function isColumnAggr(arg: any): arg is IColumnAggrTarget {
|
|||
return !!(arg.table && arg.column && arg.aggregationFunction);
|
||||
}
|
||||
|
||||
export function isPercentOfGrandTotal(arg: any): arg is IPercentOfGrandTotalTarget {
|
||||
return !!(arg as IPercentOfGrandTotalTarget).percentOfGrandTotal;
|
||||
}
|
||||
|
||||
export interface IBootstrapEmbedConfiguration {
|
||||
hostname?: string;
|
||||
embedUrl?: string;
|
||||
|
@ -1003,7 +1013,6 @@ export interface ICommonEmbedConfiguration extends IEmbedConfigurationBase {
|
|||
action?: string;
|
||||
contrastMode?: ContrastMode;
|
||||
permissions?: Permissions;
|
||||
openLinksInNewWindow?: boolean;
|
||||
}
|
||||
|
||||
export interface IReportEmbedConfiguration extends ICommonEmbedConfiguration {
|
||||
|
@ -1014,6 +1023,7 @@ export interface IReportEmbedConfiguration extends ICommonEmbedConfiguration {
|
|||
slicers?: ISlicer[];
|
||||
viewMode?: ViewMode;
|
||||
theme?: IReportTheme;
|
||||
eventHooks?: EventHooks;
|
||||
}
|
||||
|
||||
export interface IVisualEmbedConfiguration extends IReportEmbedConfiguration {
|
||||
|
@ -1058,6 +1068,7 @@ export interface IReportLoadConfiguration {
|
|||
embedUrl?: string;
|
||||
datasetBinding?: IDatasetBinding;
|
||||
contrastMode?: ContrastMode;
|
||||
eventHooks?: EventHooks;
|
||||
}
|
||||
|
||||
export interface IReportCreateConfiguration {
|
||||
|
@ -1069,6 +1080,7 @@ export interface IReportCreateConfiguration {
|
|||
tokenType?: TokenType;
|
||||
theme?: IReportTheme;
|
||||
embedUrl?: string;
|
||||
eventHooks?: EventHooks;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1106,7 +1118,7 @@ export interface ISettings {
|
|||
background?: BackgroundType;
|
||||
bars?: IReportBars;
|
||||
bookmarksPaneEnabled?: boolean;
|
||||
commands?: ICommandsSettings[];
|
||||
commands?: ICommandsSettings[] | IPaginatedReportsCommandsSettings;
|
||||
customLayout?: ICustomLayout;
|
||||
extensions?: Extensions;
|
||||
filterPaneEnabled?: boolean;
|
||||
|
@ -1179,12 +1191,20 @@ export interface ISaveAsParameters {
|
|||
targetWorkspaceId?: string;
|
||||
}
|
||||
|
||||
export interface IPaginatedReportParameter {
|
||||
name: string;
|
||||
value: string | null;
|
||||
}
|
||||
|
||||
export interface IPaginatedReportLoadConfiguration {
|
||||
accessToken: string;
|
||||
id: string;
|
||||
groupId?: string;
|
||||
settings?: IPaginatedReportSettings;
|
||||
tokenType?: TokenType;
|
||||
type?: string;
|
||||
embedUrl?: string;
|
||||
parameterValues?: IPaginatedReportParameter[];
|
||||
}
|
||||
|
||||
export interface IPaginatedReportSettings {
|
||||
|
@ -1516,6 +1536,11 @@ export interface ICommandsSettings {
|
|||
seeData?: ICommandSettings;
|
||||
sort?: ICommandSettings;
|
||||
spotlight?: ICommandSettings;
|
||||
insightsAnalysis?: ICommandSettings;
|
||||
addComment?: ICommandSettings;
|
||||
groupVisualContainers?: ICommandSettings;
|
||||
summarize?: ICommandSettings;
|
||||
clearSelection?: ICommandSettings;
|
||||
}
|
||||
|
||||
export interface IPaginatedReportsCommandSettings {
|
||||
|
@ -1808,4 +1833,4 @@ export function validateCustomTheme(input: any): IError[] {
|
|||
export function validateZoomLevel(input: any): IError[] {
|
||||
const errors: any[] = Validators.zoomLevelValidator.validate(input);
|
||||
return errors ? errors.map(normalizeError) : undefined;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ export class ArrayValidator implements IValidator {
|
|||
}
|
||||
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
const fieldsPath = (path ? path + "." : "") + field + "." + i;
|
||||
const fieldsPath = (path ? path + "." : "") + field + "." + i.toString();
|
||||
for (const validator of this.itemValidators) {
|
||||
const errors = validator.validate(input[i], fieldsPath, field);
|
||||
if (errors) {
|
||||
|
@ -207,7 +207,7 @@ export class RangeValidator extends NumberValidator {
|
|||
// input is a number, now check if it's in the given range
|
||||
if(input > this.maxValue || input < this.minValue) {
|
||||
return [{
|
||||
message: field + " must be a number between " + this.minValue + " and " + this.maxValue,
|
||||
message: field + " must be a number between " + this.minValue.toString() + " and " + this.maxValue.toString(),
|
||||
path: (path ? path + "." : "") + field,
|
||||
keyword: "range"
|
||||
}];
|
||||
|
|
|
@ -47,7 +47,7 @@ import {
|
|||
import { LoadQnaValidator, QnaInterpretInputDataValidator, QnaSettingsValidator } from '../models/qnaValidator';
|
||||
import { ReportCreateValidator } from '../models/reportCreateValidator';
|
||||
import { ReportLoadValidator } from '../models/reportLoadValidator';
|
||||
import { PaginatedReportLoadValidator } from '../models/paginatedReportLoadValidator';
|
||||
import { PaginatedReportLoadValidator, ReportParameterFieldsValidator } from '../models/paginatedReportLoadValidator';
|
||||
import { SaveAsParametersValidator } from '../models/saveAsParametersValidator';
|
||||
import { SlicerTargetSelectorValidator, VisualSelectorValidator, VisualTypeSelectorValidator } from '../models/selectorsValidator';
|
||||
import { SettingsValidator, PaginatedReportSettingsValidator } from '../models/settingsValidator';
|
||||
|
@ -151,6 +151,7 @@ export const Validators = {
|
|||
paginatedReportCommandsValidator: new PaginatedReportCommandsValidator(),
|
||||
paginatedReportLoadValidator: new PaginatedReportLoadValidator(),
|
||||
paginatedReportsettingsValidator: new PaginatedReportSettingsValidator(),
|
||||
parameterValuesArrayValidator: new ArrayValidator([new ReportParameterFieldsValidator()]),
|
||||
parametersPanelValidator: new ParametersPanelValidator(),
|
||||
permissionsValidator: new EnumValidator([0, 1, 2, 4, 7]),
|
||||
playBookmarkRequestValidator: new PlayBookmarkRequestValidator(),
|
||||
|
|
|
@ -61,6 +61,26 @@ export class CommandsSettingsValidator extends ObjectValidator {
|
|||
field: "spotlight",
|
||||
validators: [Validators.singleCommandSettingsValidator]
|
||||
},
|
||||
{
|
||||
field: "insightsAnalysis",
|
||||
validators: [Validators.singleCommandSettingsValidator]
|
||||
},
|
||||
{
|
||||
field: "addComment",
|
||||
validators: [Validators.singleCommandSettingsValidator]
|
||||
},
|
||||
{
|
||||
field: "groupVisualContainers",
|
||||
validators: [Validators.singleCommandSettingsValidator]
|
||||
},
|
||||
{
|
||||
field: "summarize",
|
||||
validators: [Validators.singleCommandSettingsValidator]
|
||||
},
|
||||
{
|
||||
field: "clearSelection",
|
||||
validators: [Validators.singleCommandSettingsValidator]
|
||||
}
|
||||
];
|
||||
|
||||
const multipleFieldsValidator = new MultipleFieldsValidator(fields);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import { IFieldValidatorsPair, MultipleFieldsValidator } from '../core/multipleFieldsValidator';
|
||||
import { ObjectValidator } from '../core/typeValidator';
|
||||
import { IValidationError, Validators } from '../core/validator';
|
||||
import { IValidationError, IValidator, Validators } from '../core/validator';
|
||||
|
||||
export class PaginatedReportLoadValidator extends ObjectValidator {
|
||||
public validate(input: any, path?: string, field?: string): IValidationError[] {
|
||||
|
@ -35,6 +35,18 @@ export class PaginatedReportLoadValidator extends ObjectValidator {
|
|||
{
|
||||
field: "tokenType",
|
||||
validators: [Validators.tokenTypeValidator]
|
||||
},
|
||||
{
|
||||
field: "embedUrl",
|
||||
validators: [Validators.stringValidator]
|
||||
},
|
||||
{
|
||||
field: "type",
|
||||
validators: [Validators.stringValidator]
|
||||
},
|
||||
{
|
||||
field: "parameterValues",
|
||||
validators: [Validators.parameterValuesArrayValidator]
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -42,3 +54,24 @@ export class PaginatedReportLoadValidator extends ObjectValidator {
|
|||
return multipleFieldsValidator.validate(input, path, field);
|
||||
}
|
||||
}
|
||||
|
||||
export class ReportParameterFieldsValidator implements IValidator {
|
||||
public validate(input: any, path?: string, field?: string): IValidationError[] {
|
||||
if (input == null) {
|
||||
return null;
|
||||
}
|
||||
const fields: IFieldValidatorsPair[] = [
|
||||
{
|
||||
field: "name",
|
||||
validators: [Validators.fieldRequiredValidator, Validators.stringValidator]
|
||||
},
|
||||
{
|
||||
field: "value",
|
||||
validators: [Validators.stringValidator]
|
||||
},
|
||||
];
|
||||
|
||||
const multipleFieldsValidator = new MultipleFieldsValidator(fields);
|
||||
return multipleFieldsValidator.validate(input, path, field);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -95,7 +95,6 @@ export class SettingsValidator extends ObjectValidator {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
export class PaginatedReportSettingsValidator extends ObjectValidator {
|
||||
public validate(input: any, path?: string, field?: string): IValidationError[] {
|
||||
if (input == null) {
|
||||
|
|
|
@ -6,7 +6,7 @@ import * as models from '../src/models';
|
|||
import { IFilter, ITarget } from '../src/models';
|
||||
|
||||
describe('Unit | Models', () => {
|
||||
function testForExpectedMessage(errors: models.IError[], message: string) {
|
||||
function testForExpectedMessage(errors: models.IError[], message: string): void {
|
||||
expect(errors).toBeDefined();
|
||||
const atLeastOneMessageMatches = errors
|
||||
.some((error) => error.message === message);
|
||||
|
@ -21,7 +21,6 @@ describe('Unit | Models', () => {
|
|||
const datasetIdRequiredMessage = "datasetId is required";
|
||||
const idRequiredMessage = "id is required";
|
||||
const idInvalidTypeMessage = "id must be a string";
|
||||
const filtersInvalidMessage = "filters property is invalid";
|
||||
const pageNameInvalidTypeMessage = "pageName must be a string";
|
||||
const permissionsInvalidMessage = "permissions property is invalid";
|
||||
const permissionsInvalidTypeMessage = "permissions must be a number";
|
||||
|
@ -387,17 +386,53 @@ describe('Unit | Models', () => {
|
|||
});
|
||||
|
||||
describe('validatePaginatedReportLoad', () => {
|
||||
const testData: any = {
|
||||
accessToken: "token",
|
||||
id: "reportid",
|
||||
};
|
||||
it(`happy path`, () => {
|
||||
const testData = {
|
||||
load: {
|
||||
accessToken: "token",
|
||||
id: "reportid",
|
||||
settings: { commands: { parameterPanel: { enabled: true, expanded: true } } }
|
||||
}
|
||||
};
|
||||
const errors = models.validatePaginatedReportLoad(testData.load);
|
||||
testData.settings = { commands: { parameterPanel: { enabled: true, expanded: true } } };
|
||||
const errors = models.validatePaginatedReportLoad(testData);
|
||||
expect(errors).toBeUndefined();
|
||||
});
|
||||
it(`happy path with parameterValues`, () => {
|
||||
testData.parameterValues = [{ name: 'dummy name', value: 'dummy value' }];
|
||||
const errors = models.validatePaginatedReportLoad(testData);
|
||||
expect(errors).toBeUndefined();
|
||||
});
|
||||
it('should fail if "parameterValues" is not an array', () => {
|
||||
testData.parameterValues = 'object';
|
||||
const errors = models.validatePaginatedReportLoad(testData);
|
||||
testForExpectedMessage(errors, 'parameterValues property is invalid');
|
||||
});
|
||||
it('should fail if name field is not a string', () => {
|
||||
testData.parameterValues = [
|
||||
{
|
||||
name: {},
|
||||
value: 'dummy value'
|
||||
}
|
||||
];
|
||||
const errors = models.validatePaginatedReportLoad(testData);
|
||||
testForExpectedMessage(errors, 'parameterValues property is invalid');
|
||||
});
|
||||
it('should fail if value field is not a string or null', () => {
|
||||
testData.parameterValues = [
|
||||
{
|
||||
name: 'dummy name',
|
||||
value: 'dummy value'
|
||||
},
|
||||
{
|
||||
name: 'dummy name 2',
|
||||
value: null
|
||||
},
|
||||
{
|
||||
name: 'dummy name 3',
|
||||
value: 3
|
||||
}
|
||||
];
|
||||
const errors = models.validatePaginatedReportLoad(testData);
|
||||
testForExpectedMessage(errors, 'parameterValues property is invalid');
|
||||
});
|
||||
});
|
||||
|
||||
describe('validateDashboardLoad', () => {
|
||||
|
@ -894,6 +929,7 @@ describe('Unit | Models', () => {
|
|||
expectedFilter.target as models.IFilterTarget,
|
||||
expectedFilter.operator,
|
||||
expectedFilter.itemCount,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||
expectedFilter.orderBy as ITarget);
|
||||
|
||||
// Assert
|
||||
|
@ -1790,7 +1826,6 @@ describe('Unit | Models', () => {
|
|||
describe('validate Extensions', () => {
|
||||
const commandNameInvalidTypeMessage = "name must be a string";
|
||||
const commandNameRequiredMessage = "name is required";
|
||||
const menuLocationInvalidMessage = "menuLocation property is invalid";
|
||||
const selectorInvalidTypeMessage = "selector property is invalid";
|
||||
const visualContextMenuInvalidMessage = "visualContextMenu property is invalid";
|
||||
|
||||
|
@ -3007,11 +3042,11 @@ describe("Unit | Filters", () => {
|
|||
const keyValues = [[1, 2], [3, 4]];
|
||||
|
||||
// Act
|
||||
const attemptToCreateFilterOnColumn = () => {
|
||||
const attemptToCreateFilterOnColumn = (): models.BasicFilterWithKeys => {
|
||||
return new models.BasicFilterWithKeys({ table: "t", column: "c", keys: ["1"] }, "In", values, keyValues);
|
||||
};
|
||||
// Act
|
||||
const attemptToCreateFilterOnHierarchy = () => {
|
||||
const attemptToCreateFilterOnHierarchy = (): models.BasicFilterWithKeys => {
|
||||
return new models.BasicFilterWithKeys({ table: "t", hierarchy: "c", hierarchyLevel: "level", keys: ["1"] }, "In", values, keyValues);
|
||||
};
|
||||
expect(attemptToCreateFilterOnColumn).toThrowError();
|
||||
|
@ -3081,7 +3116,7 @@ describe("Unit | Filters", () => {
|
|||
};
|
||||
|
||||
// Act
|
||||
const attemptToCreateFilter = () => {
|
||||
const attemptToCreateFilter = (): models.AdvancedFilter => {
|
||||
return new models.AdvancedFilter({ table: "t", column: "c" }, 1 as any, condition);
|
||||
};
|
||||
|
||||
|
@ -3107,7 +3142,7 @@ describe("Unit | Filters", () => {
|
|||
];
|
||||
|
||||
// Act
|
||||
const attemptToCreateFilter = () => {
|
||||
const attemptToCreateFilter = (): models.AdvancedFilter => {
|
||||
return new models.AdvancedFilter({ table: "Table", column: "c" }, "And", ...conditions);
|
||||
};
|
||||
|
||||
|
@ -3119,7 +3154,7 @@ describe("Unit | Filters", () => {
|
|||
// Arrange
|
||||
|
||||
// Act
|
||||
const attemptToCreateFilter = () => {
|
||||
const attemptToCreateFilter = (): models.AdvancedFilter => {
|
||||
return new models.AdvancedFilter({ table: "Table", column: "c" }, "Or", { value: "a", operator: "Contains" });
|
||||
};
|
||||
|
||||
|
@ -3313,6 +3348,7 @@ describe("Unit | Filters", () => {
|
|||
expectedFilter.target as models.IFilterTarget,
|
||||
expectedFilter.operator,
|
||||
expectedFilter.itemCount,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
||||
expectedFilter.orderBy as ITarget);
|
||||
|
||||
// Assert
|
||||
|
|
41
tslint.json
41
tslint.json
|
@ -1,41 +0,0 @@
|
|||
{
|
||||
"extends": "tslint:recommended",
|
||||
"rules": {
|
||||
"max-line-length": false,
|
||||
"max-classes-per-file": false,
|
||||
"array-type": false,
|
||||
"member-access": false,
|
||||
"no-empty-interface": false,
|
||||
"indent": [
|
||||
true,
|
||||
"spaces",
|
||||
4
|
||||
],
|
||||
"object-literal-shorthand": [
|
||||
true,
|
||||
{
|
||||
"property": "never"
|
||||
}
|
||||
],
|
||||
"one-line": [
|
||||
"check-whitespace",
|
||||
"check-open-brace"
|
||||
],
|
||||
"interface-over-type-literal": false,
|
||||
"quotemark": [
|
||||
"single",
|
||||
"avoid-escape"
|
||||
],
|
||||
"trailing-comma": false,
|
||||
"whitespace": [
|
||||
"check-branch",
|
||||
"check-decl",
|
||||
"check-operator",
|
||||
"check-module",
|
||||
"check-seperator",
|
||||
"check-type"
|
||||
],
|
||||
"object-literal-sort-keys": false,
|
||||
"no-var-requires": false
|
||||
}
|
||||
}
|
|
@ -8,7 +8,6 @@
|
|||
"node_modules",
|
||||
"typings/index.d.ts",
|
||||
"dist",
|
||||
"test",
|
||||
"tmp"
|
||||
]
|
||||
}
|
Загрузка…
Ссылка в новой задаче