mirror of
https://github.com/haveno-dex/haveno-ui.git
synced 2025-08-07 14:12:33 -04:00
chore(dev): app boilerplate
Electron, React, Vite app boilerplate - license header - pre-commit and commit-msg hooks - storybook - fix windows tests; - fix linux build - CI setup - persistent store with electron-store and safeStorage - localization with react-intl Refs: - https://github.com/haveno-dex/haveno-ui/projects/1#card-81001746 - https://github.com/haveno-dex/haveno-ui/projects/1#card-81001745 Authored-by: schowdhuri Reviewed-by: localredhead
This commit is contained in:
parent
3a379a7c55
commit
a9893aa853
81 changed files with 16560 additions and 0 deletions
26
packages/preload/contracts.d.ts
vendored
Normal file
26
packages/preload/contracts.d.ts
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// 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.
|
||||
// =============================================================================
|
||||
|
||||
/* eslint-disable @typescript-eslint/consistent-type-imports */
|
||||
|
||||
interface Exposed {
|
||||
readonly nodeCrypto: Readonly<typeof import("./src/nodeCrypto").nodeCrypto>;
|
||||
readonly versions: Readonly<typeof import("./src/versions").versions>;
|
||||
readonly electronStore: Readonly<typeof import("./src/store").store>;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
interface Window extends Exposed {}
|
32
packages/preload/src/exposeInMainWorld.ts
Normal file
32
packages/preload/src/exposeInMainWorld.ts
Normal file
|
@ -0,0 +1,32 @@
|
|||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// 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.
|
||||
// =============================================================================
|
||||
|
||||
import { contextBridge } from "electron";
|
||||
|
||||
/**
|
||||
* Typesafe wrapper for `electron.contextBridge.exposeInMainWorld`.
|
||||
* Guarantees that all exposed APIs will comply with contracts.
|
||||
* @param key The key to inject the API onto window with. The API will be accessible on window[apiKey].
|
||||
* @param api Your API
|
||||
*
|
||||
* @see https://www.electronjs.org/docs/latest/api/context-bridge#contextbridgeexposeinmainworldapikey-api
|
||||
*/
|
||||
export function exposeInMainWorld<T extends keyof Exposed & string>(
|
||||
key: T,
|
||||
api: Exposed[T]
|
||||
) {
|
||||
return contextBridge.exposeInMainWorld(key, api);
|
||||
}
|
23
packages/preload/src/index.ts
Normal file
23
packages/preload/src/index.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// 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.
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* @module preload
|
||||
*/
|
||||
|
||||
import "./nodeCrypto";
|
||||
import "./versions";
|
||||
import "./store";
|
27
packages/preload/src/nodeCrypto.ts
Normal file
27
packages/preload/src/nodeCrypto.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// 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.
|
||||
// =============================================================================
|
||||
|
||||
import { type BinaryLike, createHash } from "crypto";
|
||||
import { exposeInMainWorld } from "./exposeInMainWorld";
|
||||
|
||||
function sha256sum(data: BinaryLike) {
|
||||
return createHash("sha256").update(data).digest("hex");
|
||||
}
|
||||
|
||||
// Export for types in contracts.d.ts
|
||||
export const nodeCrypto = { sha256sum } as const;
|
||||
|
||||
exposeInMainWorld("nodeCrypto", nodeCrypto);
|
27
packages/preload/src/store.ts
Normal file
27
packages/preload/src/store.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// 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.
|
||||
// =============================================================================
|
||||
|
||||
import { ipcRenderer } from "electron";
|
||||
import { exposeInMainWorld } from "./exposeInMainWorld";
|
||||
import type { UserInfoInputType } from "./types";
|
||||
|
||||
// Export for types in contracts.d.ts
|
||||
export const store = {
|
||||
storeUserinfo: async (data?: UserInfoInputType) =>
|
||||
ipcRenderer.invoke("store:userinfo", data),
|
||||
};
|
||||
|
||||
exposeInMainWorld("electronStore", store);
|
17
packages/preload/src/types/index.ts
Normal file
17
packages/preload/src/types/index.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// 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 * from "./store";
|
64
packages/preload/src/types/store.ts
Normal file
64
packages/preload/src/types/store.ts
Normal file
|
@ -0,0 +1,64 @@
|
|||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// 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.
|
||||
// =============================================================================
|
||||
|
||||
import type { Schema } from "electron-store";
|
||||
|
||||
export enum StoreKeys {
|
||||
UserInfo = "UserInfo",
|
||||
Permissions = "Permissions",
|
||||
}
|
||||
|
||||
// TS types for StoreSchema
|
||||
export interface IStoreSchema {
|
||||
[StoreKeys.UserInfo]: IUserInfo;
|
||||
[StoreKeys.Permissions]: Array<IUserPermission>;
|
||||
}
|
||||
|
||||
export interface IUserInfo {
|
||||
username: string;
|
||||
password: Buffer;
|
||||
}
|
||||
|
||||
export type UserInfoInputType = Omit<IUserInfo, "password"> & {
|
||||
password: string;
|
||||
};
|
||||
|
||||
export interface IUserPermission {
|
||||
name: string;
|
||||
}
|
||||
|
||||
// this schema is used by electron-store
|
||||
// must mirror IStoreSchema
|
||||
export const StoreSchema: Schema<IStoreSchema> = {
|
||||
[StoreKeys.UserInfo]: {
|
||||
type: "object",
|
||||
required: [],
|
||||
properties: {
|
||||
username: { type: "string" },
|
||||
},
|
||||
},
|
||||
[StoreKeys.Permissions]: {
|
||||
type: "array",
|
||||
default: [],
|
||||
items: {
|
||||
type: "object",
|
||||
required: [],
|
||||
properties: {
|
||||
name: { type: "string" },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
22
packages/preload/src/versions.ts
Normal file
22
packages/preload/src/versions.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// 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.
|
||||
// =============================================================================
|
||||
|
||||
import { exposeInMainWorld } from "./exposeInMainWorld";
|
||||
|
||||
// Export for types in contracts.d.ts
|
||||
export const versions = process.versions;
|
||||
|
||||
exposeInMainWorld("versions", versions);
|
47
packages/preload/tests/unit.spec.ts
Normal file
47
packages/preload/tests/unit.spec.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// 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.
|
||||
// =============================================================================
|
||||
|
||||
import { createHash } from "crypto";
|
||||
import { afterEach, expect, test, vi } from "vitest";
|
||||
|
||||
const exposeInMainWorldMock = vi.fn();
|
||||
vi.mock("electron", () => ({
|
||||
contextBridge: { exposeInMainWorld: exposeInMainWorldMock },
|
||||
}));
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
test("versions", async () => {
|
||||
await import("../src/versions");
|
||||
expect(exposeInMainWorldMock).toBeCalledTimes(1);
|
||||
expect(exposeInMainWorldMock).lastCalledWith("versions", process.versions);
|
||||
});
|
||||
|
||||
test("nodeCrypto", async () => {
|
||||
await import("../src/nodeCrypto");
|
||||
expect(exposeInMainWorldMock).toBeCalledTimes(1);
|
||||
expect(exposeInMainWorldMock.mock.calls[0][0]).toBe("nodeCrypto");
|
||||
expect(exposeInMainWorldMock.mock.calls[0][1]).toHaveProperty("sha256sum");
|
||||
|
||||
const data = "rawData";
|
||||
const expectedHash = createHash("sha256").update(data).digest("hex");
|
||||
|
||||
expect(exposeInMainWorldMock.mock.calls[0][1].sha256sum(data)).toBe(
|
||||
expectedHash
|
||||
);
|
||||
});
|
17
packages/preload/tsconfig.json
Normal file
17
packages/preload/tsconfig.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "esnext",
|
||||
"target": "esnext",
|
||||
"sourceMap": false,
|
||||
"moduleResolution": "Node",
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"isolatedModules": true,
|
||||
|
||||
"types": ["node"],
|
||||
|
||||
"baseUrl": "."
|
||||
},
|
||||
"include": ["src/**/*.ts", "contracts.d.ts", "../../types/**/*.d.ts"],
|
||||
"exclude": ["**/*.spec.ts", "**/*.test.ts"]
|
||||
}
|
54
packages/preload/vite.config.js
Normal file
54
packages/preload/vite.config.js
Normal file
|
@ -0,0 +1,54 @@
|
|||
// =============================================================================
|
||||
// Copyright 2022 Haveno
|
||||
//
|
||||
// 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.
|
||||
// =============================================================================
|
||||
|
||||
import { chrome } from "../../.electron-vendors.cache.json";
|
||||
import { builtinModules } from "module";
|
||||
|
||||
const PACKAGE_ROOT = __dirname;
|
||||
|
||||
/**
|
||||
* @type {import('vite').UserConfig}
|
||||
* @see https://vitejs.dev/config/
|
||||
*/
|
||||
const config = {
|
||||
mode: process.env.MODE,
|
||||
root: PACKAGE_ROOT,
|
||||
envDir: process.cwd(),
|
||||
build: {
|
||||
sourcemap: "inline",
|
||||
target: `chrome${chrome}`,
|
||||
outDir: "dist",
|
||||
assetsDir: ".",
|
||||
minify: process.env.MODE !== "development",
|
||||
lib: {
|
||||
entry: "src/index.ts",
|
||||
formats: ["cjs"],
|
||||
},
|
||||
rollupOptions: {
|
||||
external: [
|
||||
"electron",
|
||||
...builtinModules.flatMap((p) => [p, `node:${p}`]),
|
||||
],
|
||||
output: {
|
||||
entryFileNames: "[name].cjs",
|
||||
},
|
||||
},
|
||||
emptyOutDir: true,
|
||||
brotliSize: false,
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
Loading…
Add table
Add a link
Reference in a new issue