Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(infrastructure): move infrastructure code to its own package #1985

Merged
merged 31 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
86a6d74
Make an infrastructure workspace.
sbruens Apr 19, 2024
b8ad9b5
Move more modules.
sbruens Apr 19, 2024
adf9220
Add missing license header.
sbruens Apr 19, 2024
055cc11
Move `intl-messageformat` dependency to the proper workspace.
sbruens Apr 19, 2024
cc82c86
Move manager infrastructure code to new infrastructure workspace.
sbruens Apr 19, 2024
d1c6d46
Export all modules.
sbruens Apr 19, 2024
a4d2e5a
Fix `tsconfig.json`.
sbruens Apr 19, 2024
27e957d
Extend electron `tsconfig.json` from base `tsconfig.json`.
sbruens Apr 19, 2024
a52d336
Add a workflow and a build action.
sbruens Apr 19, 2024
7211609
Add a clean script.
sbruens Apr 19, 2024
eb13436
Add a commitlint scope.
sbruens Apr 19, 2024
13ea464
Add `jasmine` dep.
sbruens Apr 19, 2024
1ceccb4
Remove build action.
sbruens Apr 20, 2024
e6478ea
Don't use the jasmine config.
sbruens Apr 20, 2024
50a39c7
Remove karma.
sbruens Apr 20, 2024
6cc3285
More pruning.
sbruens Apr 20, 2024
4e962b7
Remove gitgnore change.
sbruens Apr 20, 2024
026dd24
Rename to `@outline/infrastructure`.
sbruens Apr 22, 2024
189f2a8
Merge remote-tracking branch 'origin/master' into sbruens/infra
sbruens Apr 22, 2024
ef537f0
Remove unneeded `package-lock.json`.
sbruens Apr 22, 2024
abda6b4
Lock changes.
sbruens Apr 22, 2024
f9592a9
Remove `jasmine.json`.
sbruens Apr 22, 2024
2e4b0f2
Do not run the `web_app` tests with Jasmine.
sbruens Apr 22, 2024
ab1e790
Undo license header change, which is diffed from server_manager.
sbruens Apr 22, 2024
f691b14
Fix another import.
sbruens Apr 22, 2024
00010d7
Alphabetize dependencies.
sbruens Apr 22, 2024
6882224
Merge remote-tracking branch 'origin/master' into sbruens/infra
sbruens Apr 22, 2024
9af6a86
Put `infrastructure` workspace first.
sbruens Apr 22, 2024
595f014
Merge remote-tracking branch 'origin/master' into sbruens/infra
sbruens Apr 23, 2024
f600eac
Update more import ordering.
sbruens Apr 23, 2024
92d172a
Remove double newline.
sbruens Apr 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/workflows/test_infrastructure.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Build and Test / Infrastructure

concurrency:
group: '${{ github.head_ref || github.ref }} Infrastructure'
cancel-in-progress: true

on:
pull_request:
types:
- opened
- synchronize
push:
branches:
- master

jobs:
test:
name: Infrastructure Test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/[email protected]

- name: Install Node
uses: actions/setup-node@v3
with:
node-version-file: .nvmrc
cache: npm
cache-dependency-path: ./infrastructure/package.json

- name: Install NPM Dependencies
run: npm ci

- name: Infrastructure Test
run: npm run action infrastructure/test
12 changes: 0 additions & 12 deletions client/infrastructure/i18n.ts

This file was deleted.

41 changes: 0 additions & 41 deletions client/infrastructure/memory_storage.ts

This file was deleted.

2 changes: 1 addition & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"cordova-plugin-statusbar": "^2.2.3",
"electron-updater": "^5.0.5",
"lit": "^2.2.2",
"@outline/infrastructure": "file:../infrastructure",
daniellacosse marked this conversation as resolved.
Show resolved Hide resolved
"ShadowsocksConfig": "github:Jigsaw-Code/outline-shadowsocksconfig#v0.2.1",
"socks": "^1.1.10",
"sudo-prompt": "^9.2.1",
Expand Down Expand Up @@ -95,7 +96,6 @@
"html-webpack-plugin": "^5.1.0",
"husky": "^1.3.1",
"i18n-strings-files": "^2.0.0",
"intl-messageformat": "^9.12.0",
"istanbul": "^0.4.5",
"karma": "^6.4.2",
"karma-chrome-launcher": "^3.1.0",
Expand Down
4 changes: 2 additions & 2 deletions client/src/www/app/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import * as errors from '../model/errors';
import * as events from '../model/events';
import {Server} from '../model/server';
import {OperationTimedOut} from '../../../infrastructure/timeout_promise';
import {OperationTimedOut} from '@outline/infrastructure/timeout_promise';
daniellacosse marked this conversation as resolved.
Show resolved Hide resolved
import {ServerListItem, ServerConnectionState} from '../views/servers_view';
import {SERVER_CONNECTION_INDICATOR_DURATION_MS} from '../views/servers_view/server_connection_indicator';

Expand All @@ -27,7 +27,7 @@ import {Settings, SettingsKey} from './settings';
import {Updater} from './updater';
import {UrlInterceptor} from './url_interceptor';
import {VpnInstaller} from './vpn_installer';
import {Localizer} from '../../../infrastructure/i18n';
import {Localizer} from '@outline/infrastructure/i18n';

enum OUTLINE_ACCESS_KEY_SCHEME {
STATIC = 'ss',
Expand Down
2 changes: 1 addition & 1 deletion client/src/www/app/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {makeConfig, SIP002_URI} from 'ShadowsocksConfig';
import {OutlinePlatform} from './platform';
import {Settings} from './settings';
import {TunnelFactory} from './tunnel';
import {Localizer} from '../../../infrastructure/i18n.js';
import {Localizer} from '@outline/infrastructure/i18n';

// Used to determine whether to use Polymer functionality on app initialization failure.
let webComponentsAreReady = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {InMemoryStorage} from '../../../../infrastructure/memory_storage';
import {InMemoryStorage} from '@outline/infrastructure/memory_storage';
import {ServerIncompatible, ServerUrlInvalid, ShadowsocksUnsupportedCipher} from '../../model/errors';
import {EventQueue, ServerAdded, ServerForgetUndone, ServerForgotten, ServerRenamed} from '../../model/events';

Expand Down
2 changes: 1 addition & 1 deletion client/src/www/app/settings.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {InMemoryStorage} from '../../../infrastructure/memory_storage';
import {InMemoryStorage} from '@outline/infrastructure/memory_storage';

import {Settings, SettingsKey} from './settings';

Expand Down
2 changes: 1 addition & 1 deletion client/src/www/model/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// limitations under the License.

import {Server} from './server';
import {CustomError} from '../../../infrastructure/custom_error';
import {CustomError} from '@outline/infrastructure/custom_error';

export class ServerAlreadyAdded extends CustomError {
constructor(public readonly server: Server) {
Expand Down
2 changes: 1 addition & 1 deletion client/src/www/testing/localize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
limitations under the License.
*/

import type {FormattableMessage, Localizer} from '../../../infrastructure/i18n';
import type {FormattableMessage, Localizer} from '@outline/infrastructure/i18n';
import englishMessages from '../messages/en.json';
import IntlMessageFormat from 'intl-messageformat';

Expand Down
2 changes: 1 addition & 1 deletion client/src/www/views/contact_view/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {IssueType, UNSUPPORTED_ISSUE_TYPE_HELPPAGES} from './issue_type';
import {AppType} from './app_type';
import {FormValues, SupportForm, ValidFormValues} from './support_form';
import {OutlineErrorReporter} from '../../shared/error_reporter';
import {Localizer} from '../../../../infrastructure/i18n';
import {Localizer} from '@outline/infrastructure/i18n';

/** The possible steps in the stepper. Only one step is shown at a time. */
enum Step {
Expand Down
2 changes: 1 addition & 1 deletion client/src/www/views/contact_view/support_form/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import '@material/mwc-textfield';
import {AppType} from '../app_type';
import {TextField} from '@material/mwc-textfield';
import {SelectedDetail} from '@material/mwc-menu/mwc-menu-base';
import {Localizer} from '../../../../../infrastructure/i18n';
import {Localizer} from '@outline/infrastructure/i18n';

type FormControl = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;

Expand Down
2 changes: 1 addition & 1 deletion client/src/www/views/servers_view/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import './server_list';

import {ServerListItem as _ServerListItem} from './server_list_item';
import {ServerConnectionState as _ServerConnectionState} from './server_connection_indicator';
import { Localizer } from '../../../../infrastructure/i18n';
import { Localizer } from '@outline/infrastructure/i18n';

export type ServerListItem = _ServerListItem;

Expand Down
2 changes: 1 addition & 1 deletion client/src/www/views/servers_view/server_list/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {customElement, property} from 'lit/decorators.js';

import '../server_list_item/server_card';
import {ServerListItem} from '../server_list_item';
import {Localizer} from '../../../../../infrastructure/i18n';
import {Localizer} from '@outline/infrastructure/i18n';

@customElement('server-list')
export class ServerList extends LitElement {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import {Ref} from 'lit/directives/ref';
import {Menu} from '@material/mwc-menu';
import {ServerConnectionState} from '../server_connection_indicator';
import {Localizer} from '../../../../../infrastructure/i18n';
import {Localizer} from '@outline/infrastructure/i18n';

export enum ServerListItemEvent {
CONNECT = 'ConnectPressed',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {Menu} from '@material/mwc-menu';

import {ServerListItem, ServerListItemElement, ServerListItemEvent} from '..';
import {ServerConnectionState} from '../../server_connection_indicator';
import {Localizer} from '../../../../../../infrastructure/i18n';
import {Localizer} from '@outline/infrastructure/i18n';

const sharedCSS = css`
/* TODO(daniellacosse): reset via postcss */
Expand Down
1 change: 1 addition & 0 deletions commitlint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module.exports = {
'client/electron/windows',
'devtools',
'docs',
'infrastructure',
'manager',
'manager/linux',
'manager/mac',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import * as forge from 'node-forge';

// Keys are in OpenSSH format
export class KeyPair {
sbruens marked this conversation as resolved.
Show resolved Hide resolved
export interface KeyPair {
public: string;
private: string;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,25 @@ describe('LanguageMatcher', () => {
const SUPPORTED_LANGUAGES = i18n.languageList(['es', 'pt-BR', 'ru']);
const matcher = new i18n.LanguageMatcher(SUPPORTED_LANGUAGES, undefined);
const supportedLanguage = matcher.getBestSupportedLanguage(i18n.languageList(['pt-PT']));
expect(supportedLanguage.string()).toEqual('pt-BR');
expect(supportedLanguage?.string()).toEqual('pt-BR');
});
it('returns the right variant', () => {
const SUPPORTED_LANGUAGES = i18n.languageList(['en-GB', 'en-IN', 'en-US']);
const matcher = new i18n.LanguageMatcher(SUPPORTED_LANGUAGES, undefined);
const supportedLanguage = matcher.getBestSupportedLanguage(i18n.languageList(['en-IN']));
expect(supportedLanguage.string()).toEqual('en-IN');
expect(supportedLanguage?.string()).toEqual('en-IN');
});
it('prefers first matched user language', () => {
const SUPPORTED_LANGUAGES = i18n.languageList(['en-US', 'pt-BR']);
const matcher = new i18n.LanguageMatcher(SUPPORTED_LANGUAGES, undefined);
const supportedLanguage = matcher.getBestSupportedLanguage(i18n.languageList(['cn', 'en-GB', 'pt-BR']));
expect(supportedLanguage.string()).toEqual('en-US');
expect(supportedLanguage?.string()).toEqual('en-US');
});
it('returns default on no match', () => {
const SUPPORTED_LANGUAGES = i18n.languageList(['es', 'pt-BR', 'ru']);
const matcher = new i18n.LanguageMatcher(SUPPORTED_LANGUAGES, new i18n.LanguageCode('fr'));
const supportedLanguage = matcher.getBestSupportedLanguage(i18n.languageList(['cn']));
expect(supportedLanguage.string()).toEqual('fr');
expect(supportedLanguage?.string()).toEqual('fr');
});
it('returns undefined on no match and no default', () => {
const SUPPORTED_LANGUAGES = i18n.languageList(['es', 'pt-BR', 'ru']);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {PrimitiveType, FormatXMLElementFn} from 'intl-messageformat';

export type FormattableMessage =
| string
| symbol
| object
| PrimitiveType
| FormatXMLElementFn<symbol | object, string | symbol | object | (string | symbol | object)[]>;

export interface Localizer {
(messageID: string, ...formatKeyValueList: FormattableMessage[]): string;
}

export class LanguageCode {
private language: string;
private normalizedLanguage: string;
Expand All @@ -32,7 +45,7 @@ export class LanguageCode {
}

export class LanguageMatcher {
constructor(private supportedLanguages: LanguageCode[], private defaultLanguage: LanguageCode = undefined) {}
constructor(private supportedLanguages: LanguageCode[], private defaultLanguage?: LanguageCode) {}

// Goes over each user language, trying to find the supported language that matches
// the best. We'll trim variants of the user and supported languages in order to find
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// limitations under the License.

export class InMemoryStorage implements Storage {
readonly length: number;
readonly length = 0;
sbruens marked this conversation as resolved.
Show resolved Hide resolved
[key: string]: {};
[index: number]: string;

Expand Down
21 changes: 21 additions & 0 deletions infrastructure/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "@outline/infrastructure",
"version": "0.0.0",
"private": true,
"description": "Shared infrastructure code.",
"scripts": {
"clean": "rm -rf node_modules"
},
"devDependencies": {
"@types/jasmine": "^5.1.4",
"@types/node-forge": "^1.3.11",
"https-browserify": "^1.0.0",
"intl-messageformat": "^10.5.11",
"jasmine": "^5.1.0",
"stream-http": "^3.2.0",
"typescript": "^5.4.5"
},
"dependencies": {
"node-forge": "^1.3.1"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {PathApiClient} from './path_api';
import {type HttpRequest, type HttpResponse, PathApiClient} from './path_api';

describe('PathApi', () => {
// Mock fetcher
let lastRequest: HttpRequest;
let nextResponse: Promise<HttpResponse>;
let lastRequest: HttpRequest | undefined;
let nextResponse: Promise<HttpResponse> | undefined;

const fetcher = (request: HttpRequest) => {
const fetcher = (request: HttpRequest): Promise<HttpResponse> => {
lastRequest = request;
return nextResponse;
return nextResponse!;
};

beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,14 @@ export class PathApiClient {
try {
response = await this.fetcher(request);
} catch (e) {
throw new ServerApiError(`API request to ${path} failed due to network error: ${e.message}`);
const msg = e instanceof Error ? e.message : 'unknown';
throw new ServerApiError(`API request to ${path} failed due to network error: ${msg}`);
}
if (response.status < 200 || response.status >= 300) {
throw new ServerApiError(`API request to ${path} failed with status ${response.status}`, response);
}
if (!response.body) {
return;
return undefined as T;
sbruens marked this conversation as resolved.
Show resolved Hide resolved
}
// Assume JSON and unsafe cast to `T`.
return JSON.parse(response.body);
Expand Down
File renamed without changes.
File renamed without changes.
26 changes: 26 additions & 0 deletions infrastructure/test.action.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash -eu
#
# Copyright 2024 The Outline Authors
#
# 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.

set -e

readonly TEST_DIR="${BUILD_DIR}/js/infrastructure/"
rm -rf "${TEST_DIR}"

# Use commonjs modules, jasmine runs in node.
tsc -p "${ROOT_DIR}/infrastructure" --outDir "${TEST_DIR}" --module commonjs
jasmine "output/build/js/**/*.spec.js"

rm -rf "${TEST_DIR}"
Loading
Loading