Skip to content

Commit

Permalink
refactor(infrastructure): move infrastructure code to its own package (
Browse files Browse the repository at this point in the history
…#1985)

* Make an infrastructure workspace.

* Move more modules.

* Add missing license header.

* Move `intl-messageformat` dependency to the proper workspace.

* Move manager infrastructure code to new infrastructure workspace.

* Export all modules.

* Fix `tsconfig.json`.

* Extend electron `tsconfig.json` from base `tsconfig.json`.

* Add a workflow and a build action.

* Add a clean script.

* Add a commitlint scope.

* Add `jasmine` dep.

* Remove build action.

* Don't use the jasmine config.

* Remove karma.

* More pruning.

* Remove gitgnore change.

* Rename to `@outline/infrastructure`.

* Remove unneeded `package-lock.json`.

* Lock changes.

* Remove `jasmine.json`.

* Do not run the `web_app` tests with Jasmine.

* Undo license header change, which is diffed from server_manager.

* Fix another import.

* Alphabetize dependencies.

* Put `infrastructure` workspace first.

* Update more import ordering.

* Remove double newline.
  • Loading branch information
sbruens authored Apr 23, 2024
1 parent 983c630 commit ffc913c
Show file tree
Hide file tree
Showing 61 changed files with 471 additions and 243 deletions.
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",
"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 @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {Localizer} from '@outline/infrastructure/i18n';
import {OperationTimedOut} from '@outline/infrastructure/timeout_promise';

import {Clipboard} from './clipboard';
import {EnvironmentVariables} from './environment';
Expand All @@ -20,8 +22,6 @@ 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 {OperationTimedOut} from '../../../infrastructure/timeout_promise';
import * as errors from '../model/errors';
import * as events from '../model/events';
import {Server} from '../model/server';
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 @@ -15,6 +15,7 @@
import '../ui_components/app-root.js';


import {Localizer} from '@outline/infrastructure/i18n';
import {makeConfig, SIP002_URI} from 'ShadowsocksConfig';

import {App} from './app';
Expand All @@ -23,7 +24,6 @@ import {OutlineServerRepository} from './outline_server_repository';
import {OutlinePlatform} from './platform';
import {Settings} from './settings';
import {TunnelFactory} from './tunnel';
import {Localizer} from '../../../infrastructure/i18n.js';
import {EventQueue} from '../model/events';

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

import {InMemoryStorage} from '@outline/infrastructure/memory_storage';
import {makeConfig, SIP002_URI} from 'ShadowsocksConfig';

import {OutlineServerRepository, ServersStorageV0, ServersStorageV1, serversStorageV0ConfigToAccessKey} from '.';
import {OutlineServer} from './server';
import {InMemoryStorage} from '../../../../infrastructure/memory_storage';
import {ServerIncompatible, ServerUrlInvalid, ShadowsocksUnsupportedCipher} from '../../model/errors';
import {EventQueue, ServerAdded, ServerForgetUndone, ServerForgotten, ServerRenamed} from '../../model/events';
import {FakeOutlineTunnel} from '../fake_tunnel';
Expand Down
3 changes: 2 additions & 1 deletion client/src/www/app/settings.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

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

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


const FAKE_SETTINGS_KEYS = ['key', 'key1', 'key2'];
Expand Down
3 changes: 2 additions & 1 deletion client/src/www/model/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

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

import {Server} from './server';
import {CustomError} from '../../../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,9 +14,9 @@
limitations under the License.
*/

import type {FormattableMessage, Localizer} from '@outline/infrastructure/i18n';
import IntlMessageFormat from 'intl-messageformat';

import type {FormattableMessage, Localizer} from '../../../infrastructure/i18n';
import englishMessages from '../messages/en.json';

export const localize: Localizer = (messageID: string, ...formatKeyValueList: FormattableMessage[]): string => {
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 @@ -22,6 +22,7 @@ import '@material/mwc-radio';
import '@material/mwc-select';
import '@material/mwc-formfield';

import {Localizer} from '@outline/infrastructure/i18n';
import {html, css, LitElement, TemplateResult, nothing} from 'lit';
import {customElement, property, state} from 'lit/decorators.js';
import {Ref, createRef, ref} from 'lit/directives/ref.js';
Expand All @@ -31,7 +32,6 @@ import './support_form';
import {AppType} from './app_type';
import {IssueType, UNSUPPORTED_ISSUE_TYPE_HELPPAGES} from './issue_type';
import {FormValues, SupportForm, ValidFormValues} from './support_form';
import {Localizer} from '../../../../infrastructure/i18n';
import {OutlineErrorReporter} from '../../shared/error_reporter';

/** The possible steps in the stepper. Only one step is shown at a time. */
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 @@ -21,12 +21,12 @@ import '@material/mwc-select';
import '@material/mwc-textarea';
import '@material/mwc-textfield';

import {Localizer} from '@outline/infrastructure/i18n';
import {html, css, LitElement, TemplateResult, nothing, PropertyValues} from 'lit';
import {customElement, property, state} from 'lit/decorators.js';
import {live} from 'lit/directives/live.js';
import {createRef, Ref, ref} from 'lit/directives/ref.js';

import {Localizer} from '../../../../../infrastructure/i18n';
import {AppType} from '../app_type';


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 @@ -16,6 +16,7 @@

import '@material/mwc-button';

import { Localizer } from '@outline/infrastructure/i18n';
import {css, html, LitElement} from 'lit';
import {customElement, property} from 'lit/decorators.js';
import { DirectiveResult } from 'lit/directive';
Expand All @@ -25,7 +26,6 @@ import {ServerConnectionState as _ServerConnectionState} from './server_connecti
import './server_connection_indicator';
import './server_list';
import {ServerListItem as _ServerListItem} from './server_list_item';
import { Localizer } from '../../../../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 @@ -11,11 +11,11 @@
limitations under the License.
*/

import {Localizer} from '@outline/infrastructure/i18n';
import {css, html, LitElement} from 'lit';
import {customElement, property} from 'lit/decorators.js';

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

@customElement('server-list')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@

import {Menu} from '@material/mwc-menu';

import {type Localizer} from '@outline/infrastructure/i18n';
import {Ref} from 'lit/directives/ref';

import {Localizer} from '../../../../../infrastructure/i18n';
import {ServerConnectionState} from '../server_connection_indicator';

export enum ServerListItemEvent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@ import '@material/mwc-button';
import '@material/mwc-icon-button';
import '@material/mwc-menu';

import {Localizer} from '@outline/infrastructure/i18n';
import {css, html, LitElement} from 'lit';
import {customElement, property} from 'lit/decorators.js';
import {createRef, Ref, ref} from 'lit/directives/ref.js';


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

const sharedCSS = css`
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 {
export interface KeyPair {
public: string;
private: string;
}
Expand Down
File renamed without changes.
File renamed without changes.
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
15 changes: 14 additions & 1 deletion server_manager/infrastructure/i18n.ts → infrastructure/i18n.ts
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;
[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"
}
}
Loading

0 comments on commit ffc913c

Please sign in to comment.