Skip to content

Latest commit

 

History

History
261 lines (177 loc) · 9.31 KB

CONTRIBUTING.md

File metadata and controls

261 lines (177 loc) · 9.31 KB

Contribute Guide

A guide on how to participate in this project.

Before "Contribution":

Issues

Pulsate accepts the following issues:

These issues can be submitted by filling out the form.

If the issue type you wish to submit is not listed here, you can submit an empty issue here.

Please check the following points before submission.

  • Similar issues have not already been submitted.
    • Click here to check.
  • (Bug report only) Is it not a security-related bug?
    • If you are submitting such a bug report, you must submit it in an appropriate manner, not as an Issue. Please check our security policy for details.

Pull Requests

Pulsate welcomes pull request submissions.

To submit a pull request to Pulsate, you need to clarify why this change is needed, summary of changes.

When you try to submit a pull request, a pre-prepared template will be displayed as a placeholder. Follow the template to describe the pull request you are submitting.

Before submitting a pull request, please check the following points:

  • Check to see if the pull request you are submitting is the same as the one you are submitting.
    • Click here to check.
  • You are not trying to submit a PR that is still in progress.
  • Pull request title conforms to Conventional Commits

After finishing, please run pnpm format to format the code. (If you are using VSCode, it will be formatted automatically.)

Once it has been reviewed and approved by the Pulsate maintainer, it can be merged.

Review

During the review, keep the following in mind.

  • Answer questions from the maintainer.
    • Reply to any questions about changes from the maintainer during the review. This will be helpful during the review.

Commit Message

Pulsate commit messages must follow conventional commit.

  • The commit message should be in the following form.
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]
  • The type must be the correct "type" for the change.
    • For example, Add new feature is feat, Fix bug is fix.
  • If you make any backward-compatibility-breaking changes, you must set scope to ! and add a description of the destructive change to body.
    • Please contact the maintainer via Issue or Discussion once you make such a change. In most cases, such changes are not desired.

Development Environment

Pulsate assumes the following development environment.

Fixing and installing the Node.js version

In order to develop with Pulsate, you need to fix the version of Node.js using the following tools.

  • mise (recommended)
    • This is a version control tool compatible with asdf. It is recommended to use mise unless there is some inconvenience.
  • asdf
    • With .tool-versions file, you can also fix the version of Node.js with asdf.

Warning

If you are using a version of Node.js other than v20.x, which is the required environment for Pulsate, commands such as pnpm run will not be available to maintain compatibility. Please fix your version before starting development.

To use mise, follow these steps:

  1. Install mise. See mise installation guide for details.
  2. Run mise install in the Pulsate root directory.
  3. Run node --version and make sure your Node.js version is 20.x.

Install the package

Pulsate uses pnpm to manage packages. Run the following command to install the package.

# If pnpm is not enabled:

corepack enable pnpm
pnpm install

Generate and update Prisma Client

To generate a Prisma Client from a defined Prisma schema, execute the following command. (Originally defined in the prepare script, this is done automatically when updating dependencies.)

pnpm build:prisma

This command will create a Prisma Client in node_modules/.prisma/client. You can import the client from here when you want to use it.

If you change the model, you can update the Prisma Client by running this command again.

Style Guide

A style guide for Pulsate development.

  • These settings are bound by Prettier, ESLint, .editorconfig.
    • Some editors and IDEs require special plug-ins to be installed.
    • For more details, click here.

  • All files must have spaces at the end of lines removed.
    • In the case of Markdown, it is not necessary to remove it because it also means a line break.
  • All files must have a single newline at the end.
  • All files should be opened with space intent.
    • The size of the intent is about 2 characters.
  • Use lf for line breaks.
  • Use utf-8 character encoding.

TypeScript

The basic naming conventions follow the TypeScript Coding guidelines.

Acronyms and contractions of compound words are counted as one word. For example, for UUUID, use Uuid. For HTTPS, use Https.

In cases where the word is a single character, such as X_CONTENT, the _ is omitted and XCONTENT is used.

Also, in situations where camelCase should be used, it is counted as a single word. For example, the name of a variable representing an account ID is accountId.

  • The variable and function name is camelCase.

  • The class name is PascalCase.

    • The class member and method name is camelCase.
  • The interface name is PascalCase.

    • The interface member name is camelCase.
  • The enum name and member is PascalCase.

  • The type name is PascalCase.

    • The type member name is camelCase.
  • The namespace name is PascalCase.

  • The file name should be in camelCase.

    • Use lowercase for a single word.

null and undefined

Pulsate uses a functional programming library called mini-fn.

mini-fn has a direct sum type Option<T>, so you don't have to think whether the type should be T | undefined or T | null.

There is a dedicated function to handle the direct sum type, so you can use Option or Result instead if you want to handle null or undefined types.

/* Type Guard. Required for TypeScript to determine the type at code branches. */

// The `res` in this state is of type `Option<Account>` and it is not determined whether the value exists or not.
const res = await this.accountRepository.findByName(name);
// Check whether the value `res` exists or not by type guarding. If not, it is an error.
if (Option.isNone(res)) {
  return Result.err(new Error('account not found'));
}
// Fix `res` as `account`.
const account = Option.unwrap(res);

If you need to define a property whose value may not exist. Do not use null or undefined, but use ?.

// Good
interface Foo {
  x?: string;
}

// Bad
interface Foo {
  x: string | undefined;
  y: string | null;
}

any and unknown

Do not use any, use unknown.

If you use an API with typing that returns any, immediately make a type assertion to unknown.

// Good
const foo = 'apple' as unknown

// Bad
const foo = 'apple' as any

Quote marks

Use single quotes for strings.

// Good
const a = 'hoge';

// Bad
const a = "hoge";

Arrays

Use annotations when declaring arrays to ensure readability.

// Good
const a: string[]

// Bad
const a: Array<string>

Database Schema Migration

Pulsate uses Prisma to manage the database schema migration.
For more information, see the Prisma documentation.