Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into papi-slice-1
Browse files Browse the repository at this point in the history
  • Loading branch information
bitdivine committed Sep 30, 2024
2 parents 7a87a65 + 9c739d0 commit 06dfaf4
Show file tree
Hide file tree
Showing 180 changed files with 3,550 additions and 1,999 deletions.
78 changes: 2 additions & 76 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,77 +1,3 @@
module.exports = {
root: true,
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:svelte/recommended',
'prettier'
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'eslint-plugin-local-rules', 'import'],
parserOptions: {
sourceType: 'module',
ecmaVersion: 2020,
extraFileExtensions: ['.svelte'],
project: ['./tsconfig.eslint.json']
},
env: {
browser: true,
es2017: true,
node: true
},
overrides: [
{
files: ['*.svelte'],
parser: 'svelte-eslint-parser',
parserOptions: {
parser: '@typescript-eslint/parser'
}
},
{
files: ['scripts/**/*.mjs', 'scripts/**/*.ts'],
rules: {
'no-console': 'off'
}
},
{
files: ['*.svelte'],
rules: {
'import/order': [
'error',
{
alphabetize: { order: 'asc' }
}
]
}
}
],
rules: {
'@typescript-eslint/no-inferrable-types': 'error',
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
'@typescript-eslint/no-unused-vars': [
'warn',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_'
}
],
'@typescript-eslint/prefer-nullish-coalescing': 'error',
'@typescript-eslint/prefer-reduce-type-parameter': 'error',
'arrow-body-style': ['warn', 'as-needed'],
curly: 'error',
'local-rules/prefer-object-params': 'warn',
'local-rules/no-svelte-store-in-api': 'error',
'local-rules/use-option-type-wrapper': 'warn',
'import/no-duplicates': ['error', { 'prefer-inline': true }],
'no-console': ['error', { allow: ['error', 'warn'] }],
'no-continue': 'warn',
'no-delete-var': 'error',
'no-else-return': ['warn', { allowElseIf: false }],
'no-unused-vars': 'off',
'prefer-template': 'error'
},
globals: {
NodeJS: true
}
};
extends: ["@dfinity/eslint-config-oisy-wallet/svelte"],
};
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 39 additions & 0 deletions HACKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ This document lists a couple of useful information for development and deploymen
- [Faucets](#faucets)
- [Testing](#testing)
- [Integrate ckERC20 Tokens](#integrate-ckerc20-tokens)
- [Routes Styles](#routes-styles)

## Deployment

Expand Down Expand Up @@ -218,3 +219,41 @@ Before they become available, there must be a new block mined. You can mine one:
```bash
./scripts/add.tokens.bitcoin.sh
```

# Routes Styles

The designer, or the foundation, might want to use different background colors for specific routes, such as using white generally speaking in the wallet and light blue on the signer (`/sign`) route.

On the other hand, we want to prerender the background color because, if we don’t, the user will experience a "glitchy" loading effect where the dapp initially loads with a white background before applying the correct color.

That's why, when there is such a specific requests, some CSS can be defined at the route level. CSS which is then prerendered within the generated HTML page at build time.

For example, if I wanted to add a route `/hello` with a red background, we would add the following files in `src`:

```
src/routes/(group)/hello/+page.svelte
src/routes/(group)/hello/+oisy.page.css
```

And in the CSS:

```css
:root {
background: red;
}
```

Furthermore, given that parsing happens at build time, the developer might want to load the style at runtime for local development purposes. This can be achieved by importing the style in the related `+layout.svelte`:

```javascript
<script lang="ts">
import { LOCAL } from '$lib/constants/app.constants';

onMount(async () => {
if (!LOCAL) {
return;
}
await import('./+oisy.page.css');
});
</script>
```
24 changes: 12 additions & 12 deletions e2e/utils/pages/homepage.page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,39 @@ import { HOMEPAGE_URL, LOCAL_REPLICA_URL } from '../constants/e2e.constants';
import { getQRCodeValueFromDataURL } from '../qr-code.utils';
import { getReceiveTokensModalQrCodeButtonSelector } from '../selectors.utils';

type HomepageParams = {
interface HomepageParams {
page: Page;
viewportSize?: ViewportSize;
};
}

type HomepageLoggedInParams = {
iiPage: InternetIdentityPage;
} & HomepageParams;

type SelectorOperationParams = {
interface SelectorOperationParams {
selector: string;
};
}

type TestIdOperationParams = {
interface TestIdOperationParams {
testId: string;
};
}

type WaitForModalParams = {
interface WaitForModalParams {
modalOpenButtonTestId: string;
modalTestId: string;
};
}

type TestModalSnapshotParams = {
selectorsToMock?: string[];
} & WaitForModalParams;

type ClickMenuItemParams = {
interface ClickMenuItemParams {
menuItemTestId: string;
};
}

type WaitForLocatorOptions = {
interface WaitForLocatorOptions {
state: 'attached' | 'detached' | 'visible' | 'hidden';
};
}

abstract class Homepage {
readonly #page: Page;
Expand Down
4 changes: 2 additions & 2 deletions env.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ export const readCanisterIds = ({
prefix?: string;
}): Record<string, string> => {
try {
type Details = {
interface Details {
ic?: string;
staging?: string;
local?: string;
};
}

const config: Record<string, Details> = JSON.parse(readFileSync(filePath, 'utf8'));

Expand Down
177 changes: 1 addition & 176 deletions eslint-local-rules.cjs
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,176 +1 @@
const { isNullish, nonNullish } = require('@dfinity/utils');
module.exports = {
'no-svelte-store-in-api': {
meta: {
docs: {
description:
'Svelte stores should not be used in APIs since they are also utilized by workers.',
category: 'Possible Errors',
recommended: false
},
schema: []
},
create(context) {
return {
ImportDeclaration(node) {
const filePath = context.getFilename();

const {
source: { value }
} = node;

if (filePath.includes('/api/') && value === 'svelte/store') {
context.report({
node,
message: "Importing 'svelte/store' is not allowed in API modules."
});
}
}
};
}
},
'use-option-type-wrapper': {
meta: {
type: 'suggestion',
docs: {
description: 'Enforce use of Option<T> instead of T | null | undefined',
category: 'Best Practices',
recommended: true
},
fixable: 'code',
schema: []
},
create: function (context) {
const checkForOptionType = (node) => {
if (
node.typeAnnotation.type === 'TSUnionType' &&
node.typeAnnotation.types.length === 3 &&
node.typeAnnotation.types.some((t) => t.type === 'TSNullKeyword') &&
node.typeAnnotation.types.some((t) => t.type === 'TSUndefinedKeyword')
) {
const type = node.typeAnnotation.types.find(
(t) => t.type !== 'TSNullKeyword' && t.type !== 'TSUndefinedKeyword'
);

const typeText =
type.type === 'TSTypeReference' && type.typeName && type.typeName.name
? type.typeName.name
: context.getSourceCode().getText(type);

if (type) {
try {
context.report({
node,
message: `Use Option<${typeText}> instead of ${typeText} | null | undefined.`,
fix(fixer) {
return fixer.replaceText(node.typeAnnotation, `Option<${typeText}>`);
}
});
} catch (e) {
console.error(e);
console.log(type);
}
}
}
};

return {
TSTypeAnnotation(node) {
checkForOptionType(node);
},
TSTypeAliasDeclaration(node) {
checkForOptionType(node);
}
};
}
},
'prefer-object-params': {
meta: {
type: 'suggestion',
docs: {
description:
'Enforce passing parameters as an object when a function has more than one parameter',
category: 'Best Practices',
recommended: true
},
schema: []
},
create(context) {
const checkForMoreThanOneParameter = (node) => {
const parent = node.parent;

// Check if it is a callback for looping methods
if (
nonNullish(parent) &&
parent.type === 'CallExpression' &&
parent.callee.type === 'MemberExpression' &&
['map', 'reduce', 'forEach', 'filter', 'sort', 'replace'].includes(
parent.callee.property.name
)
) {
return;
}

// Check if it is a callback for Array.from
if (
nonNullish(parent) &&
parent.type === 'CallExpression' &&
parent.callee.type === 'MemberExpression' &&
parent.callee.object.name === 'Array' &&
parent.callee.property.name === 'from'
) {
return;
}

// Check if it is a callback in a Promise constructor
if (
nonNullish(parent) &&
parent.type === 'NewExpression' &&
parent.callee.name === 'Promise'
) {
return;
}

// Check if it is a callback in JSON.stringify
if (
nonNullish(parent) &&
parent.type === 'CallExpression' &&
parent.callee.type === 'MemberExpression' &&
parent.callee.object.name === 'JSON' &&
parent.callee.property.name === 'stringify'
) {
return;
}

// Check if it is inside a class constructor
if (
nonNullish(parent) &&
parent.type === 'MethodDefinition' &&
parent.kind === 'constructor'
) {
return;
}

if (node.params.length > 1) {
context.report({
node,
message:
'Functions with more than one parameter should accept an object and use destructuring.'
});
}
};

return {
FunctionDeclaration(node) {
checkForMoreThanOneParameter(node);
},
FunctionExpression(node) {
checkForMoreThanOneParameter(node);
},
ArrowFunctionExpression(node) {
checkForMoreThanOneParameter(node);
}
};
}
}
};
module.exports = require("@dfinity/eslint-config-oisy-wallet/eslint-local-rules");
Loading

0 comments on commit 06dfaf4

Please sign in to comment.