Merge pull request #2879 from spotify/rugvip/ts4

cli: add support for ts4
This commit is contained in:
Patrik Oldsberg
2020-10-19 12:30:56 +02:00
committed by GitHub
45 changed files with 243 additions and 197 deletions
@@ -17,7 +17,7 @@
import { mergeDatabaseConfig } from './config';
describe('config', () => {
describe(mergeDatabaseConfig, () => {
describe('mergeDatabaseConfig', () => {
it('does not mutate the input object', () => {
const input = {
original: 'key',
@@ -26,7 +26,7 @@ describe('database connection', () => {
},
]);
describe(createDatabaseClient, () => {
describe('createDatabaseClient', () => {
it('returns a postgres connection', () => {
expect(
createDatabaseClient(
@@ -44,7 +44,7 @@ describe('postgres', () => {
},
]);
describe(buildPgDatabaseConfig, () => {
describe('buildPgDatabaseConfig', () => {
it('builds a postgres config', () => {
const mockConnection = createMockConnection();
@@ -125,7 +125,7 @@ describe('postgres', () => {
});
});
describe(getPgConnectionConfig, () => {
describe('getPgConnectionConfig', () => {
it('returns the connection object back', () => {
const mockConnection = createMockConnection();
const config = createConfig(mockConnection);
@@ -163,7 +163,7 @@ describe('postgres', () => {
});
});
describe(createPgDatabaseClient, () => {
describe('createPgDatabaseClient', () => {
it('creates a postgres knex instance', () => {
expect(
createPgDatabaseClient(
@@ -188,8 +188,8 @@ describe('postgres', () => {
});
});
describe(parsePgConnectionString, () => {
it('parses a connection string uri ', () => {
describe('parsePgConnectionString', () => {
it('parses a connection string uri', () => {
expect(
parsePgConnectionString(
'postgresql://postgres:pass@foobar:5432/dbname?ssl=true',
@@ -32,7 +32,7 @@ describe('sqlite3', () => {
},
]);
describe(buildSqliteDatabaseConfig, () => {
describe('buildSqliteDatabaseConfig', () => {
it('buidls a string connection', () => {
expect(buildSqliteDatabaseConfig(createConfig(':memory:'))).toEqual({
client: 'sqlite3',
@@ -72,7 +72,7 @@ describe('sqlite3', () => {
});
});
describe(createSqliteDatabaseClient, () => {
describe('createSqliteDatabaseClient', () => {
it('creates an in memory knex instance', () => {
expect(
createSqliteDatabaseClient(
-2
View File
@@ -14,8 +14,6 @@
* limitations under the License.
*/
/* eslint-disable @typescript-eslint/camelcase */
import { resolve as resolvePath } from 'path';
/**
+12 -3
View File
@@ -38,7 +38,9 @@
"@rollup/plugin-json": "^4.0.2",
"@rollup/plugin-node-resolve": "^8.1.0",
"@rollup/plugin-yaml": "^2.1.1",
"@spotify/eslint-config": "^7.0.1",
"@spotify/eslint-config-base": "^8.0.0",
"@spotify/eslint-config-react": "^8.0.0",
"@spotify/eslint-config-typescript": "^8.0.0",
"@sucrase/webpack-loader": "^2.0.0",
"@svgr/plugin-jsx": "5.4.x",
"@svgr/plugin-svgo": "5.4.x",
@@ -47,6 +49,8 @@
"@types/start-server-webpack-plugin": "^2.2.0",
"@types/webpack-env": "^1.15.2",
"@types/webpack-node-externals": "^2.5.0",
"@typescript-eslint/eslint-plugin": "^v3.10.1",
"@typescript-eslint/parser": "^v3.10.1",
"bfj": "^7.0.2",
"chalk": "^4.0.0",
"chokidar": "^3.3.1",
@@ -56,9 +60,14 @@
"diff": "^4.0.2",
"esbuild": "^0.7.7",
"eslint": "^7.1.0",
"eslint-config-prettier": "^6.0.0",
"eslint-formatter-friendly": "^7.0.0",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-jest": "^24.1.0",
"eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-plugin-monorepo": "^0.2.1",
"eslint-plugin-react": "^7.12.4",
"eslint-plugin-react-hooks": "^4.0.0",
"fork-ts-checker-webpack-plugin": "^4.0.5",
"fs-extra": "^9.0.0",
"handlebars": "^4.7.3",
@@ -84,12 +93,12 @@
"rollup-pluginutils": "^2.8.2",
"start-server-webpack-plugin": "^2.2.5",
"style-loader": "^1.2.1",
"sucrase": "^3.14.1",
"sucrase": "^3.16.0",
"tar": "^6.0.1",
"terser-webpack-plugin": "^1.4.3",
"ts-jest": "^26.0.0",
"ts-loader": "^7.0.4",
"typescript": "^3.9.3",
"typescript": "^4.0.3",
"url-loader": "^4.1.0",
"webpack": "^4.41.6",
"webpack-dev-server": "^3.11.0",
+2 -2
View File
@@ -17,7 +17,7 @@
import { isParallelDefault, parseParallel } from './parallel';
describe('parallel', () => {
describe(parseParallel, () => {
describe('parseParallel', () => {
it('coerces "false" string to boolean', () => {
expect(parseParallel('false')).toBeFalsy();
});
@@ -44,7 +44,7 @@ describe('parallel', () => {
});
});
describe(isParallelDefault, () => {
describe('isParallelDefault', () => {
it('returns true if default value', () => {
expect(isParallelDefault(undefined)).toBeTruthy();
expect(isParallelDefault(true)).toBeTruthy();
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createApiRef } from '../ApiRef';
import { createApiRef, ApiRef } from '../system';
import { Observable } from '../../types';
export type AlertMessage = {
@@ -38,7 +38,7 @@ export type AlertApi = {
alert$(): Observable<AlertMessage>;
};
export const alertApiRef = createApiRef<AlertApi>({
export const alertApiRef: ApiRef<AlertApi> = createApiRef({
id: 'core.alert',
description: 'Used to report alerts and forward them to the app',
});
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { createApiRef } from '../ApiRef';
import { ApiRef, createApiRef } from '../system';
import { BackstageTheme } from '@backstage/theme';
import { Observable } from '../../types';
import { SvgIconProps } from '@material-ui/core';
@@ -77,7 +77,7 @@ export type AppThemeApi = {
setActiveThemeId(themeId?: string): void;
};
export const appThemeApiRef = createApiRef<AppThemeApi>({
export const appThemeApiRef: ApiRef<AppThemeApi> = createApiRef({
id: 'core.apptheme',
description: 'API Used to configure the app theme, and enumerate options',
});
@@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createApiRef } from '../ApiRef';
import { ApiRef, createApiRef } from '../system';
import { Config } from '@backstage/config';
// Using interface to make the ConfigApi name show up in docs
export type ConfigApi = Config;
export const configApiRef = createApiRef<ConfigApi>({
export const configApiRef: ApiRef<ConfigApi> = createApiRef({
id: 'core.config',
description: 'Used to access runtime configuration',
});
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createApiRef } from '../ApiRef';
import { ApiRef, createApiRef } from '../system';
/**
* The discovery API is used to provide a mechanism for plugins to
@@ -41,7 +41,7 @@ export type DiscoveryApi = {
getBaseUrl(pluginId: string): Promise<string>;
};
export const discoveryApiRef = createApiRef<DiscoveryApi>({
export const discoveryApiRef: ApiRef<DiscoveryApi> = createApiRef({
id: 'core.discovery',
description: 'Provides service discovery of backend plugins',
});
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { createApiRef } from '../ApiRef';
import { ApiRef, createApiRef } from '../system';
import { Observable } from '../../types';
/**
@@ -62,7 +62,7 @@ export type ErrorApi = {
error$(): Observable<{ error: Error; context?: ErrorContext }>;
};
export const errorApiRef = createApiRef<ErrorApi>({
export const errorApiRef: ApiRef<ErrorApi> = createApiRef({
id: 'core.error',
description: 'Used to report errors and forward them to the app',
});
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { createApiRef } from '../ApiRef';
import { ApiRef, createApiRef } from '../system';
import { UserFlags, FeatureFlagsRegistry } from '../../app/FeatureFlags';
import { FeatureFlagName } from '../../plugin';
@@ -57,7 +57,7 @@ export interface FeatureFlagsRegistryItem {
name: FeatureFlagName;
}
export const featureFlagsApiRef = createApiRef<FeatureFlagsApi>({
export const featureFlagsApiRef: ApiRef<FeatureFlagsApi> = createApiRef({
id: 'core.featureflags',
description: 'Used to toggle functionality in features across Backstage',
});
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createApiRef } from '../ApiRef';
import { ApiRef, createApiRef } from '../system';
import { ProfileInfo } from './auth';
/**
@@ -51,7 +51,7 @@ export type IdentityApi = {
signOut(): Promise<void>;
};
export const identityApiRef = createApiRef<IdentityApi>({
export const identityApiRef: ApiRef<IdentityApi> = createApiRef({
id: 'core.identity',
description: 'Provides access to the identity of the signed in user',
});
@@ -16,7 +16,7 @@
import { IconComponent } from '../../icons';
import { Observable } from '../../types';
import { createApiRef } from '../ApiRef';
import { ApiRef, createApiRef } from '../system';
/**
* Information about the auth provider that we're requesting a login towards.
@@ -127,7 +127,7 @@ export type OAuthRequestApi = {
authRequest$(): Observable<PendingAuthRequest[]>;
};
export const oauthRequestApiRef = createApiRef<OAuthRequestApi>({
export const oauthRequestApiRef: ApiRef<OAuthRequestApi> = createApiRef({
id: 'core.oauthrequest',
description: 'An API for implementing unified OAuth flows in Backstage',
});
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { createApiRef } from '../ApiRef';
import { ApiRef, createApiRef } from '../system';
import { Observable } from '../../types';
import { ErrorApi } from './ErrorApi';
@@ -65,7 +65,7 @@ export interface StorageApi {
observe$<T>(key: string): Observable<StorageValueChange<T>>;
}
export const storageApiRef = createApiRef<StorageApi>({
export const storageApiRef: ApiRef<StorageApi> = createApiRef({
id: 'core.storage',
description: 'Provides the ability to store data which is unique to the user',
});
+18 -18
View File
@@ -14,8 +14,8 @@
* limitations under the License.
*/
import { createApiRef } from '../ApiRef';
import { Observable } from '../..';
import { ApiRef, createApiRef } from '../system';
import { Observable } from '../../types';
/**
* This file contains declarations for common interfaces of auth-related APIs.
@@ -212,13 +212,13 @@ export type SessionApi = {
* Note that the ID token payload is only guaranteed to contain the user's numerical Google ID,
* email and expiration information. Do not rely on any other fields, as they might not be present.
*/
export const googleAuthApiRef = createApiRef<
export const googleAuthApiRef: ApiRef<
OAuthApi &
OpenIdConnectApi &
ProfileInfoApi &
BackstageIdentityApi &
SessionApi
>({
> = createApiRef({
id: 'core.auth.google',
description: 'Provides authentication towards Google APIs and identities',
});
@@ -229,9 +229,9 @@ export const googleAuthApiRef = createApiRef<
* See https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/
* for a full list of supported scopes.
*/
export const githubAuthApiRef = createApiRef<
export const githubAuthApiRef: ApiRef<
OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
>({
> = createApiRef({
id: 'core.auth.github',
description: 'Provides authentication towards GitHub APIs',
});
@@ -242,13 +242,13 @@ export const githubAuthApiRef = createApiRef<
* See https://developer.okta.com/docs/guides/implement-oauth-for-okta/scopes/
* for a full list of supported scopes.
*/
export const oktaAuthApiRef = createApiRef<
export const oktaAuthApiRef: ApiRef<
OAuthApi &
OpenIdConnectApi &
ProfileInfoApi &
BackstageIdentityApi &
SessionApi
>({
> = createApiRef({
id: 'core.auth.okta',
description: 'Provides authentication towards Okta APIs',
});
@@ -259,9 +259,9 @@ export const oktaAuthApiRef = createApiRef<
* See https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html#limiting-scopes-of-a-personal-access-token
* for a full list of supported scopes.
*/
export const gitlabAuthApiRef = createApiRef<
export const gitlabAuthApiRef: ApiRef<
OAuthApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
>({
> = createApiRef({
id: 'core.auth.gitlab',
description: 'Provides authentication towards GitLab APIs',
});
@@ -272,9 +272,9 @@ export const gitlabAuthApiRef = createApiRef<
* See https://auth0.com/docs/scopes/current/oidc-scopes
* for a full list of supported scopes.
*/
export const auth0AuthApiRef = createApiRef<
export const auth0AuthApiRef: ApiRef<
OpenIdConnectApi & ProfileInfoApi & BackstageIdentityApi & SessionApi
>({
> = createApiRef({
id: 'core.auth.auth0',
description: 'Provides authentication towards Auth0 APIs',
});
@@ -286,13 +286,13 @@ export const auth0AuthApiRef = createApiRef<
* - https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent
* - https://docs.microsoft.com/en-us/graph/permissions-reference
*/
export const microsoftAuthApiRef = createApiRef<
export const microsoftAuthApiRef: ApiRef<
OAuthApi &
OpenIdConnectApi &
ProfileInfoApi &
BackstageIdentityApi &
SessionApi
>({
> = createApiRef({
id: 'core.auth.microsoft',
description: 'Provides authentication towards Microsoft APIs and identities',
});
@@ -300,13 +300,13 @@ export const microsoftAuthApiRef = createApiRef<
/**
* Provides authentication for custom identity providers.
*/
export const oauth2ApiRef = createApiRef<
export const oauth2ApiRef: ApiRef<
OAuthApi &
OpenIdConnectApi &
ProfileInfoApi &
BackstageIdentityApi &
SessionApi
>({
> = createApiRef({
id: 'core.auth.oauth2',
description: 'Example of how to use oauth2 custom provider',
});
@@ -314,9 +314,9 @@ export const oauth2ApiRef = createApiRef<
/**
* Provides authentication for saml based identity providers
*/
export const samlAuthApiRef = createApiRef<
export const samlAuthApiRef: ApiRef<
ProfileInfoApi & BackstageIdentityApi & SessionApi
>({
> = createApiRef({
id: 'core.auth.saml',
description: 'Example of how to use SAML custom provider',
});
+1 -5
View File
@@ -14,10 +14,6 @@
* limitations under the License.
*/
export { ApiProvider, useApi, useApiHolder } from './ApiProvider';
export { ApiRegistry } from './ApiRegistry';
export * from './ApiRef';
export * from './types';
export * from './helpers';
export * from './system';
export * from './definitions';
export * from './implementations';
@@ -14,8 +14,7 @@
* limitations under the License.
*/
import { ApiRef } from './ApiRef';
import { ApiHolder } from './types';
import { ApiRef, ApiHolder } from './types';
/**
* An ApiHolder that queries multiple other holders from for
@@ -15,12 +15,12 @@
*/
import {
ApiRef,
ApiFactoryHolder,
ApiFactory,
AnyApiRef,
AnyApiFactory,
} from './types';
import { ApiRef } from './ApiRef';
type ApiFactoryScope =
| 'default' // Default factories registered by core and plugins
@@ -16,8 +16,7 @@
import React, { FC, createContext, useContext, ReactNode } from 'react';
import PropTypes from 'prop-types';
import { ApiRef } from './ApiRef';
import { ApiHolder, TypesToApiRefs } from './types';
import { ApiRef, ApiHolder, TypesToApiRefs } from './types';
import { ApiAggregator } from './ApiAggregator';
type ApiProviderProps = {
@@ -14,17 +14,13 @@
* limitations under the License.
*/
import type { ApiRef } from './types';
export type ApiRefConfig = {
id: string;
description: string;
};
export type ApiRef<T> = {
id: string;
description: string;
T: T;
};
class ApiRefImpl<T> implements ApiRef<T> {
constructor(private readonly config: ApiRefConfig) {
const valid = config.id
@@ -14,8 +14,7 @@
* limitations under the License.
*/
import { ApiRef } from './ApiRef';
import { ApiHolder } from './types';
import { ApiRef, ApiHolder } from './types';
type ApiImpl<T = unknown> = readonly [ApiRef<T>, T];
@@ -14,8 +14,8 @@
* limitations under the License.
*/
import { ApiRef } from './ApiRef';
import {
ApiRef,
ApiHolder,
ApiFactoryHolder,
AnyApiRef,
@@ -14,8 +14,7 @@
* limitations under the License.
*/
import { ApiFactory, TypesToApiRefs } from './types';
import { ApiRef } from './ApiRef';
import { ApiRef, ApiFactory, TypesToApiRefs } from './types';
/**
* Used to infer types for a standalone ApiFactory that isn't immediately passed
@@ -0,0 +1,23 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { ApiProvider, useApi, useApiHolder } from './ApiProvider';
export { ApiRegistry } from './ApiRegistry';
export { ApiResolver } from './ApiResolver';
export { ApiFactoryRegistry } from './ApiFactoryRegistry';
export { createApiRef } from './ApiRef';
export * from './types';
export * from './helpers';
@@ -14,7 +14,11 @@
* limitations under the License.
*/
import { ApiRef } from './ApiRef';
export type ApiRef<T> = {
id: string;
description: string;
T: T;
};
export type AnyApiRef = ApiRef<unknown>;
+1 -2
View File
@@ -54,8 +54,7 @@ import {
} from '../apis';
import { useAsync } from 'react-use';
import { AppIdentity } from './AppIdentity';
import { ApiFactoryRegistry } from '../apis/ApiFactoryRegistry';
import { ApiResolver } from '../apis/ApiResolver';
import { ApiResolver, ApiFactoryRegistry } from '../apis/system';
type FullAppOptions = {
apis: Iterable<AnyApiFactory>;
+1 -1
View File
@@ -16,7 +16,7 @@
import { ComponentType } from 'react';
import { RouteRef } from '../routing';
import { AnyApiFactory } from '../apis';
import { AnyApiFactory } from '../apis/system';
export type RouteOptions = {
// Whether the route path must match exactly, defaults to true.
+1 -1
View File
@@ -31,7 +31,7 @@
"fs-extra": "^9.0.0",
"github-slugger": "^1.3.0",
"ts-node": "^8.6.2",
"typescript": "^3.9.3"
"typescript": "^4.0.3"
},
"devDependencies": {
"@types/fs-extra": "^9.0.1",
-4
View File
@@ -49,10 +49,6 @@ const main = (argv: string[]) => {
process.exit(1);
});
if (!process.argv.slice(2).length) {
program.outputHelp(chalk.yellow);
}
program.parse(argv);
};
+1 -5
View File
@@ -28,11 +28,7 @@
"techdocs-cli": "bin/techdocs-cli"
},
"devDependencies": {
"@spotify/eslint-config": "^7.0.0",
"@spotify/prettier-config": "^7.0.0",
"@types/serve-handler": "^6.1.0",
"eslint": "^7.1.0",
"eslint-plugin-import": "^2.22.0"
"@types/serve-handler": "^6.1.0"
},
"files": [
"bin",