diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 851640e674..dbccbe558b 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,9 +1,5 @@ -## Description - - - -## Notes for the release - - - + +- If this PR updates API docs, preview them by running `bun preview-api-docs` +- Read the full [contributing documentation](https://github.com/emberjs/data/blob/main/contributing/become-a-contributor.md) +- If you do not have permission to add labels or run the test-suite in CI, a team member will do this for you. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0a75eb9d5d..d22ce849b4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,6 +9,7 @@ detailing how to become involved to best ensure your contributions are successfu - [Becoming a Contributor](./contributing/become-a-contributor.md) - [Requesting Features or Deprecations](./contributing/rfc-process.md) - [Submitting Pull Requests](./contributing/submitting-prs.md) +- [Writing API Docs](./contributing/writing-api-docs.md) - [Linking the project to your application locally](./contributing/linking-to-applications.md) - [Key Concepts](./contributing/key-concepts.md) diff --git a/contributing/become-a-contributor.md b/contributing/become-a-contributor.md index 949c1cfedc..bb6af74f1b 100644 --- a/contributing/become-a-contributor.md +++ b/contributing/become-a-contributor.md @@ -9,6 +9,7 @@ or [RFCs](https://github.com/emberjs/rfcs/labels/T-ember-data), we coordinate wo - [Setting Up The Project](./setting-up-the-project.md) - [Project Architecture](./project-architecture.md) +- [Writing API Docs](./writing-api-docs.md) - [Key Concepts](./key-concepts.md) - [Terminology](./terminology.md) - [RFC Process](./rfc-process.md) diff --git a/contributing/writing-api-docs.md b/contributing/writing-api-docs.md new file mode 100644 index 0000000000..895bbec9ff --- /dev/null +++ b/contributing/writing-api-docs.md @@ -0,0 +1,319 @@ +# Writing API Docs + +API Documentation is generated from [yuidoc](https://yui.github.io/yuidoc/) comments in the source code. + +YUIDoc syntax is very similar to [JSDoc](https://jsdoc.app/) but there are occassional nuances where +it becomes best to know the underlying parser is YUIDoc. + +While API Documentation lives with the source-code, the code itself plays no-part in the documentation +that is generated: everything is compiled from comments alone. + +
+ +--- + +
+ +## Documentation Syntax + +
+ +### What are Doc Comments + +Only `**` comments are compiled as potential documentation, e.g. + +```ts +/** + * This is a potential documentation block + */ +``` + +Where as single star comment blocks are not considered documentation + +```ts +/* + * This is not a potential documentation block + */ +``` + +
+ +### Ignored Doc Comments + +When compiling the API documentation, several categories of comments will be ignored: + +- `@internal` - signifies internal documentation for contributors for a non-public API +- `@feature` - signifies documentation for an unreleased feature gated by a canary flag +- `@typedoc` - signifies typescript-only (in-editor) documentation that should not be compiled into the API docs + +Additionally, use of the following tags will cause a doc comment to be ignored due to intended use primarily being docs +written for in-editor experience similar to `@typedoc` + +- `@see` +- `@link` +- `@inheritdoc` + +For example, the below doc comment would be ignored + +```ts +/** + * This is a private utility for updating the state + * of a relationship. + * + * @internal + */ +``` + +
+ +### Always Start with `@module` + +The YUIDocs parser will attribute all documentation it discovers to the most recent +`module` (package) declaration it has seen. For this reason, any file that has documentation +comments should declare the package it applies to at the top of the file. + +For instance, if we were writing documentation for a feature within the `@ember-data/store` +package, we would declare the following at the top of the file: + +```ts +/** + * @module @ember-data/store + */ +``` + +### Doc Comments can be Markdown + +Doc comments can contain most any valid markdown syntax, most markdown-valid html, +and can utilize code-highlighting via language prefix on a code block comment. + +For instance + +```ts +/** + * ## Overview + * + * Some details + * + * ### An Example + * + * ```ts + * new Store(); + * ``` + * + * @class Store + * @public + */ +``` + +
+ +### Doc Comments should start every line with a `*` + +While technically doc comments only need to start with `/**`, providing a `*` for +every line with matching indentation ensures correct parsing of all tags and documentation. + +Without this, some decorators in code examples may be incorrectly parsed as documentation tags, +and some documentation may be unexpectedly truncated. + +**Good** + +```ts +/** + * ## Overview + * + * Some details + * + * ### An Example + * + * ```ts + * class User extends Model { + * @attr name; + * } + * ``` + * + * @class Store + * @public + */ +``` + +**Bad** + +```ts +/** + ## Overview + + Some details + + ### An Example + + \```ts + class User extends Model { + @attr name; + } + \``` + + @class Store + @public +*/ +``` + +### Documenting Modules + +Yuidoc syntax refers to packages as "modules". To declare that some code +is part of a module, we use `@module `, so the package `@warp-drive/core-types` +is `@module @warp-drive/core-types`. + +Modules are documented using a special `@main` tag. + +For instance, to write documentation giving an overview of `@warp-drive/core-types` +we would do the following. + +```ts +/** + * This package provides essential types and symbols used + * by all the other WarpDrive/EmberData packages. + * + * @module @warp-drive/core-types + * @main @warp-drive/core-types + */ +``` + +Sometimes we may want to reuse the documentation for a primary default export +class as the module documentation as well. In this case `@module` will be +declared standalone while `@main` will be affixed to the exported class doc comment. + +```ts +/** + * @module @ember-data/serializer/json-api + */ +/** + * << module (and class) overview goes here >> + * + * @class JSONAPISerializer + * @main @ember-data/serializer/json-api + * @public + */ +``` + +
+ +### Documenting Classes + +Classes are documented using `@class`. + +```ts +/** + * @since 1.13.0 + * @class JSONAPIAdapter + * @main @ember-data/adapter/json-api + * @public + * @constructor + * @extends RESTAdapter +*/ +``` + +Methods are documented with `@method` and attatch to the most recent class the parser has +seen. + +```ts +/** + * Some documentation + * + * @method myMethod + * @public + * @param {AType} myParam explanation of the param + * @return {AnotherType} explanation of the return value + */ +``` + +Properties are documented with `@property` and attach to the most recent class the parser has seen. + +```ts +/** + * An explanation of the property + * + * @property {SomeType} propertyName + * @public + */ +``` + +Static methods and properties can be documented by adding `@static` to the definition. + +
+ +### Documenting Functions + +Functions are documented as "static" methods on modules. For instance the method `recordIdentifierFor` +imported from `@ember-data/store` would be done like the below + +```ts +/** + * Description of the function + * + * @public + * @static + * @for @ember-data/store + * @param {Object} record a record instance previously obstained from the store. + * @return {StableRecordIdentifier} + */ +``` + + +
+ +### Documenting Interfaces and Types + +Yuidoc and the ember API docs do not have a mechanism for documenting types. However, because +documentation is entirely doc-comment driven, we can document interfaces and types as classes, +and mark them as such by giving them impossible names. Generally we follow the convention of +` AnInterface` and ` AType` for this. + +For example, the interface for creating a request handler is documented as a class below +whose name is ` Handler`. + +```ts +/** + * << Handler Documentation >> + * + * @class Handler + * @public + */ +``` + +
+ +--- + +
+ +## Documentation Hygeine + +
+ +### Documentation Tests + +Run `pnpm test:docs` + +This will lint discovered doc comments for common sources of error, as well as validate that no published documentation +has been added or removed unexpectedly. + +If documentation has been added, an entry for it should be added to `tests/docs/fixtures/expected.js`. +If documentation has been removed, similarly any entry for it should be removed from `tests/docs/fixtures/expected.js`. + +If documentation you've added is not being discovered by the test, it is likely that either + +- it may have been excluded due to using an [ignored doc comment](#ignored-doc-comments) +- it may have been excluded due to not using the right [comment syntax](#what-are-doc-comments) +- it may have been included in the list of paths to search for source code documentation in [yuidoc.json](../docs-generator/yuidoc.json) + +
+ +### Previewing Documentation + +Run `bun preview-api-docs` from the project root or the `docs-viewer` directory. + +This will build and run the (external) api-docs app with the current state of the api docs in the repo. + +Changes need to be manually rebuilt with `bun rebuild-api-docs`. + +See the [Docs Viewer README](../docs-viewer/README.md) for more info. diff --git a/packages/core-types/src/schema/fields.ts b/packages/core-types/src/schema/fields.ts index 9f9f269945..e38117dfb7 100644 --- a/packages/core-types/src/schema/fields.ts +++ b/packages/core-types/src/schema/fields.ts @@ -1548,7 +1548,7 @@ export type Schema = ResourceSchema | ObjectSchema; * @static * @for @warp-drive/core-types * @param {ResourceSchema} schema - * @returns {ResourceSchema} the passed in schema + * @return {ResourceSchema} the passed in schema * @public */ export function resourceSchema(schema: T): T { @@ -1565,7 +1565,7 @@ export function resourceSchema(schema: T): T { * @static * @for @warp-drive/core-types * @param {ObjectSchema} schema - * @returns {ObjectSchema} the passed in schema + * @return {ObjectSchema} the passed in schema * @public */ export function objectSchema(schema: T): T { @@ -1579,7 +1579,7 @@ export function objectSchema(schema: T): T { * @static * @for @warp-drive/core-types * @param schema - * @returns {boolean} + * @return {boolean} * @public */ export function isResourceSchema(schema: ResourceSchema | ObjectSchema): schema is ResourceSchema { @@ -1593,7 +1593,7 @@ export function isResourceSchema(schema: ResourceSchema | ObjectSchema): schema * @static * @for @warp-drive/core-types * @param schema - * @returns {boolean} + * @return {boolean} * @public */ export function isLegacyResourceSchema(schema: ResourceSchema | ObjectSchema): schema is LegacyResourceSchema { diff --git a/packages/experiments/src/persisted-cache/cache.ts b/packages/experiments/src/persisted-cache/cache.ts index 02ea4b68e7..a73753bd3c 100644 --- a/packages/experiments/src/persisted-cache/cache.ts +++ b/packages/experiments/src/persisted-cache/cache.ts @@ -182,7 +182,7 @@ export class PersistedCache implements Cache { * @method peek * @internal * @param {StableRecordIdentifier | StableDocumentIdentifier} identifier - * @returns {ResourceDocument | ResourceBlob | null} the known resource data + * @return {ResourceDocument | ResourceBlob | null} the known resource data */ peekRemoteState(identifier: StableRecordIdentifier>): T | null; peekRemoteState(identifier: StableDocumentIdentifier): ResourceDocument | null;