2018-08-04 03:28:27 +01:00
# Contribution Guidelines
2025-04-16 23:51:30 +01:00
- Include documentation reference(s) at the top of each file as a comment. For example:
2018-10-23 23:44:50 +01:00
2019-08-06 17:51:13 +01:00
```ts
2018-10-23 23:44:50 +01:00
// http://officeopenxml.com/WPdocument.php
```
2023-03-16 03:24:51 +00:00
<!-- cSpell:ignore datypic -->
2025-04-16 23:51:30 +01:00
2023-02-27 21:06:54 +00:00
It can be a link to `officeopenxml.com` or `datypic.com` etc.
It could also be a reference to the official ECMA-376 standard: https://www.ecma-international.org/publications-and-standards/standards/ecma-376/
2025-04-16 23:51:30 +01:00
- Include a portion of the schema as a comment for cross reference. For example:
2023-02-27 21:06:54 +00:00
```ts
// < xsd:element name = "tbl" type = "CT_Tbl" minOccurs = "0" maxOccurs = "1" / >
```
2025-04-16 23:51:30 +01:00
- Follow Prettier standards, and consider using the [Prettier VSCode ](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode ) plugin.
2018-10-23 23:44:50 +01:00
2025-04-16 23:51:30 +01:00
- Follow the `ESLint` rules
2018-10-23 23:44:50 +01:00
2018-10-21 04:50:57 +01:00
## Always think about the user
2022-09-15 20:00:50 +01:00
Put yourself in their position, and imagine how they would feel about the feature you wrote.
2018-10-21 04:50:57 +01:00
2019-04-04 15:35:41 -04:00
1. Is it easy to use?
2018-10-21 04:50:57 +01:00
2. Has it been documented well?
2019-04-04 15:35:41 -04:00
3. Is it intuitive?
2020-07-30 11:42:55 +01:00
4. Is it declarative?
2018-10-21 04:50:57 +01:00
5. Is it fun to use?
## Good Commit Names
Please write good commit messages when making a commit: https://chris.beams.io/posts/git-commit/
**Do not:**
2020-07-30 11:42:55 +01:00
2022-07-06 14:05:37 +01:00
<!-- cspell:disable -->
2025-04-16 23:51:30 +01:00
2018-10-21 04:50:57 +01:00
```
c // What?
2022-07-06 14:05:37 +01:00
rtl // Adding acronyms without explaining anything else is not helpful
2018-10-21 04:50:57 +01:00
works! // Glad its working, but the message is not helpful
demo updated // Getting better, but capitalize the first letter
Unesesary coment removed // Make sure to use correct spelling
```
2025-04-16 23:51:30 +01:00
2022-07-06 14:05:37 +01:00
<!-- cspell:enable -->
2018-10-21 04:50:57 +01:00
2018-10-23 23:44:50 +01:00
**Do**
2018-11-13 14:38:26 +00:00
2019-04-04 15:35:41 -04:00
`ITableFloatOptions` is an interface for a JSON of primitives. The end user would need to pass in a json object and not need to worry about the internals:
2018-11-13 14:38:26 +00:00
2019-08-06 17:51:13 +01:00
```ts
2018-10-23 23:44:50 +01:00
public float(tableFloatOptions: ITableFloatOptions): Table
```
2018-08-04 03:28:27 +01:00
2022-07-06 14:05:37 +01:00
## Declarative API
2018-08-07 01:25:28 +01:00
2022-07-06 14:05:37 +01:00
Make sure the API is declarative, so no _method calling_ or _mutation_ . This is a design decision, consistent with the rest of the project. There are benefits to declarative code over other styles of code, explained here: https://dzone.com/articles/why-declarative-coding-makes-you-a-better-programm
2018-08-07 01:25:28 +01:00
2020-07-30 11:42:55 +01:00
**Do not:**
2018-08-07 01:25:28 +01:00
2020-07-30 11:42:55 +01:00
```ts
const paragraph = doc.createParagraph();
const text = paragraph.createText();
text.contents = "Hello World";
```
2018-08-07 01:25:28 +01:00
2020-07-30 11:42:55 +01:00
**Do**
2018-08-07 01:25:28 +01:00
2020-07-30 11:42:55 +01:00
```ts
2021-03-19 20:53:56 +00:00
const doc = new Document({
sections: [{
children: [
new Paragraph({
children: [new TextRun("Hello World")],
}),
],
}];
2020-07-30 11:42:55 +01:00
});
```
2018-08-07 01:25:28 +01:00
## Getters and Setters
Getters and Setters are done with a capital letter like so:
2019-08-06 17:51:13 +01:00
```ts
2018-08-07 01:25:28 +01:00
public get Level() {
2018-10-23 23:44:50 +01:00
...
2018-08-07 01:25:28 +01:00
}
```
2020-07-30 11:42:55 +01:00
This is the convention of this project. There is no performance advantage by doing this. It means we don't need to prefix all private variables with `_` :
2018-08-07 01:25:28 +01:00
2018-10-21 04:50:57 +01:00
**Do not:**
2018-08-07 01:25:28 +01:00
2019-08-06 17:51:13 +01:00
```ts
2018-08-07 01:25:28 +01:00
private get _level: string;
```
2018-10-21 04:50:57 +01:00
**Do**
2018-08-07 01:25:28 +01:00
2019-08-06 17:51:13 +01:00
```ts
2018-08-07 01:25:28 +01:00
private get level: string;
```
2025-04-16 23:51:30 +01:00
## Types over interfaces
2018-10-21 04:50:57 +01:00
2025-04-16 23:51:30 +01:00
Using `type` aliases in TypeScript offers several advantages over `interfaces` :
2018-10-21 04:50:57 +01:00
2025-04-16 23:51:30 +01:00
- **Flexibility with Complex Types**: `type` supports defining unions, intersections, and other complex type constructs that `interfaces` cannot handle. For example:
2018-10-21 04:50:57 +01:00
2025-04-16 23:51:30 +01:00
```typescript
type StringOrNumber = string | number;
type Combined = TypeA & TypeB;
```
2018-10-21 04:50:57 +01:00
2025-04-16 23:51:30 +01:00
- **Support for Primitive Types**: `type` can alias primitive types (e.g., `type ID = string` ), while `interfaces` are limited to object shapes.
- **Tuple and Array Types**: `type` allows defining tuples and specific array types easily (e.g., `type Point = [number, number]` ), which `interfaces` cannot represent.
- **Utility Types Compatibility**: `type` works seamlessly with TypeScript's utility types (e.g., `Partial<T>` , `Pick<T, K>` ), enabling more expressive type transformations.
- **Functional Programming**: `type` is ideal for functional programming patterns, such as defining function signatures or mapped types, due to its versatility.
- **No Declaration Merging**: Unlike `interfaces` , type does not support declaration merging, which can prevent accidental type extensions and ensure predictable type definitions.
- **Consistent Pattern**: This project uses `type` for all type definitions, so using `type` for all type definitions maintains consistency and readability across the codebase.
2018-10-21 04:50:57 +01:00
2025-04-16 23:51:30 +01:00
Detailed discussion: https://stackoverflow.com/questions/37233735/typescript-interfaces-vs-types
2018-10-21 04:50:57 +01:00
**Do:**
2019-08-06 17:51:13 +01:00
```ts
2018-10-21 04:50:57 +01:00
interface IRelationshipFileInfo {
id: number;
target: string;
}
```
2025-04-16 23:51:30 +01:00
**Do not:**
```ts
type RelationshipFileInfo = { id: number; target: string };
```
2018-10-21 04:50:57 +01:00
## String enums vs type
To take full advantage of TypeScript's typing system, its best to use `string enums` :
**Do not:**
2019-08-06 17:51:13 +01:00
```ts
2018-10-21 04:50:57 +01:00
type WeaponType = "bow" | "sword" | "wand";
```
**Do:**
2019-08-06 17:51:13 +01:00
```ts
2018-10-21 04:50:57 +01:00
enum WeaponType = {
BOW = "bow",
SWORD = "sword",
WAND = "wand",
}
```
2019-03-05 13:32:09 +00:00
## Spell correctly, in full and in American English
2018-10-21 04:50:57 +01:00
**Do not:**
2020-07-30 11:42:55 +01:00
2019-08-06 17:51:13 +01:00
```ts
2020-07-30 11:42:55 +01:00
readdy; // misspelling
perm; // abbreviation
conf; // abbreviation
cnty; // abbreviation
relationFile; // abbreviation
colour; // U.K. English
2018-10-21 04:50:57 +01:00
```
**Do:**
2020-07-30 11:42:55 +01:00
2019-08-06 17:51:13 +01:00
```ts
2020-07-30 11:42:55 +01:00
ready;
permission;
config;
country;
relationshipFile;
color;
2018-10-21 04:50:57 +01:00
```
## Keep files small (within reason)
To minimize merge conflicts, reduce complexity, and improve readability, keep the files small.
## Name files and folders with `/foo-bar/kebab-case.ts`
To be consistent and in-line with the project, name files `like-this.ts` .
https://stackoverflow.com/questions/7273316/what-is-the-javascript-filename-naming-convention
2018-08-04 03:28:27 +01:00
## Testing
Please write a test of every file you make and suffix it with `.spec.ts` .
Here is a template of a test:
2019-08-06 17:51:13 +01:00
```ts
2023-06-08 13:30:31 +01:00
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2018-08-04 03:28:27 +01:00
describe("ClassName", () => {
2023-06-08 13:30:31 +01:00
afterEach(() => {
// TODO
});
2018-08-04 03:28:27 +01:00
beforeEach(() => {
// TODO
});
describe("#methodName ()", () => {
it("should ", () => {
// TODO
});
});
});
```
2018-10-21 04:50:57 +01:00
Try not to use the `tests/utility.ts` file as this is being deprecated.