From ca731dbd9354db0a2f4851b7d8e5e14bf8faa09c Mon Sep 17 00:00:00 2001 From: Seokju Na Date: Fri, 28 Nov 2025 21:09:30 +0900 Subject: [PATCH 1/5] implements note features --- src/lib.rs | 1 + src/note.rs | 366 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 367 insertions(+) create mode 100644 src/note.rs diff --git a/src/lib.rs b/src/lib.rs index 354efe6..9e9afe0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,6 +13,7 @@ pub mod ignore; pub mod index; pub mod mailmap; pub mod merge; +pub mod note; pub mod object; pub mod oid; pub mod rebase; diff --git a/src/note.rs b/src/note.rs new file mode 100644 index 0000000..5d22ea3 --- /dev/null +++ b/src/note.rs @@ -0,0 +1,366 @@ +use crate::repository::Repository; +use crate::signature::{Signature, SignaturePayload}; +use git2::Oid; +use napi::bindgen_prelude::*; +use napi_derive::napi; + +#[napi] +/// A structure representing a [note][1] in git. +/// +/// [1]: http://alblue.bandlem.com/2011/11/git-tip-of-week-git-notes.html +pub struct Note { + pub(crate) inner: SharedReference>, +} + +#[napi] +impl Note { + #[napi] + /// Get the note object's id + /// + /// @category Note/Methods + /// @signature + /// ```ts + /// class Note { + /// id(): string; + /// } + /// ``` + /// + /// @returns The note object's id. + pub fn id(&self) -> String { + self.inner.id().to_string() + } + + #[napi] + /// Get the note author + /// + /// @category Note/Methods + /// @signature + /// ```ts + /// class Note { + /// author(): Signature; + /// } + /// ``` + /// + /// @returns The note author signature. + pub fn author(&self) -> crate::Result { + let sig = self.inner.author(); + Signature::try_from(sig) + } + + #[napi] + /// Get the note committer + /// + /// @category Note/Methods + /// @signature + /// ```ts + /// class Note { + /// committer(): Signature; + /// } + /// ``` + /// + /// @returns The note committer signature. + pub fn committer(&self) -> crate::Result { + let sig = self.inner.committer(); + Signature::try_from(sig) + } + + #[napi] + /// Get the note message as a string. + /// + /// @category Note/Methods + /// @signature + /// ```ts + /// class Note { + /// message(): string; + /// } + /// ``` + /// + /// @returns The note message as a string + /// @throws Throws error if message is not utf-8. + pub fn message(&self) -> crate::Result { + let message = std::str::from_utf8(self.inner.message_bytes())?; + Ok(message.to_string()) + } +} + +#[napi(object)] +#[derive(Default)] +pub struct FindNoteOptions { + pub notes_ref: Option, +} + +#[napi(object)] +#[derive(Default)] +pub struct CreateNoteOptions { + /// Signature of the notes commit author. + /// + /// If not provided, the default signature of the repository will be used. + /// If there is no default signature set for the repository, an error will occur. + pub author: Option, + /// Signature of the notes commit commiter. + /// + /// If not provided, the default signature of the repository will be used. + /// If there is no default signature set for the repository, an error will occur. + pub committer: Option, + /// canonical name of the reference to use. + /// + /// Defaults to "refs/notes/commits". + pub notes_ref: Option, + /// Overwrite existing note. + pub force: Option, +} + +#[napi(object)] +#[derive(Default)] +pub struct DeleteNoteOptions { + /// Signature of the notes commit author. + /// + /// If not provided, the default signature of the repository will be used. + /// If there is no default signature set for the repository, an error will occur. + pub author: Option, + /// Signature of the notes commit commiter. + /// + /// If not provided, the default signature of the repository will be used. + /// If there is no default signature set for the repository, an error will occur. + pub committer: Option, + /// canonical name of the reference to use. + /// + /// Defaults to "refs/notes/commits". + pub notes_ref: Option, +} + +#[napi(iterator)] +/// An iterator over all of the notes within a repository. +pub struct Notes { + pub(crate) inner: SharedReference>, +} + +#[napi(object)] +pub struct NoteIterItem { + pub note_id: String, + pub annotated_id: String, +} + +#[napi] +impl Generator for Notes { + type Yield = NoteIterItem; + type Next = (); + type Return = (); + + fn next(&mut self, _value: Option) -> Option { + self.inner.next().and_then(|x| { + x.ok().map(|(note_id, annotated_id)| NoteIterItem { + note_id: note_id.to_string(), + annotated_id: annotated_id.to_string(), + }) + }) + } +} + +#[napi] +impl Repository { + #[napi] + /// Add a note for an object + /// + /// The `notesRef` argument is the canonical name of the reference to use, + /// defaulting to "refs/notes/commits". If `force` is specified then + /// previous notes are overwritten. + /// + /// @category Repository/Methods + /// @signature + /// ```ts + /// class Repository { + /// note(oid: string, note: string, options?: CreateNoteOptions | null | undefined): string; + /// } + /// ``` + /// + /// @param {string} oid - OID of the git object to decorate. + /// @param {string} note - Content of the note to add for object oid. + /// @param {CreateNoteOptions} [options] - Options for creating note. + /// @returns OID for the note. + pub fn note(&self, oid: String, note: String, options: Option) -> crate::Result { + let opts = options.unwrap_or_default(); + let oid = Oid::from_str(&oid)?; + let author = opts + .author + .and_then(|x| Signature::try_from(x).ok()) + .and_then(|x| git2::Signature::try_from(x).ok()) + .or_else(|| self.inner.signature().ok()) + .ok_or(crate::Error::SignatureNotFound)?; + let committer = opts + .committer + .and_then(|x| Signature::try_from(x).ok()) + .and_then(|x| git2::Signature::try_from(x).ok()) + .or_else(|| self.inner.signature().ok()) + .ok_or(crate::Error::SignatureNotFound)?; + let notes_ref = opts.notes_ref; + let force = opts.force.unwrap_or_default(); + let note_oid = self + .inner + .note(&author, &committer, notes_ref.as_deref(), oid, ¬e, force)?; + Ok(note_oid.to_string()) + } + + #[napi] + /// Get the default notes reference for this repository + /// + /// @category Repository/Methods + /// @signature + /// ```ts + /// class Repository { + /// noteDefaultRef(): string; + /// } + /// ``` + /// + /// @returns The default notes reference. + pub fn note_default_ref(&self) -> crate::Result { + let default_ref = self.inner.note_default_ref()?; + Ok(default_ref) + } + + #[napi] + /// Creates a new iterator for notes in this repository. + /// + /// The `notesRef` argument is the canonical name of the reference to use, + /// defaulting to "refs/notes/commits". + /// + /// @category Repository/Methods + /// @signature + /// ```ts + /// class Repository { + /// notes(notesRef?: string | null | undefined): Notes; + /// } + /// ``` + /// + /// @param {string} [notesRef] - The canonical name of the reference to use. + /// @returns Iterator of all notes. The iterator returned yields pairs of `[string, string]` + /// where first element is the id of the note and the second id is the id the note is annotating. + /// + /// @example + /// ```ts + /// import { openRepository } from 'es-git'; + /// + /// const repo = await openRepository('.'); + /// for (const { noteId, annotatedId } of repo.notes()) { + /// const note = repo.getNote(noteId); + /// const commit = repo.getCommit(annotatedId); + /// } + /// ``` + pub fn notes(&self, this: Reference, env: Env, notes_ref: Option) -> crate::Result { + let inner = this.share_with(env, |repo| { + repo + .inner + .notes(notes_ref.as_deref()) + .map_err(crate::Error::from) + .map_err(|e| e.into()) + })?; + Ok(Notes { inner }) + } + + #[napi] + /// Read the note for an object. + /// + /// The `notesRef` argument is the canonical name of the reference to use, + /// defaulting to "refs/notes/commits". + /// + /// The id specified is the Oid of the git object to read the note from. + /// + /// @category Repository/Methods + /// @signature + /// ```ts + /// class Repository { + /// getNote(id: string, options?: FindNoteOptions | null | undefined): Note; + /// } + /// ``` + /// + /// @param {string} id - OID of the git object to read the note from. + /// @param {FindNoteOptions} [options] - Options for finding note. + /// @returns Instance of the note. + /// @throws Throws error if note does not exists. + pub fn get_note( + &self, + this: Reference, + env: Env, + id: String, + options: Option, + ) -> crate::Result { + let opts = options.unwrap_or_default(); + let oid = Oid::from_str(&id)?; + let notes_ref = opts.notes_ref; + let inner = this.share_with(env, |repo| { + repo + .inner + .find_note(notes_ref.as_deref(), oid) + .map_err(crate::Error::from) + .map_err(|e| e.into()) + })?; + Ok(Note { inner }) + } + + #[napi] + /// Read the note for an object. + /// + /// The `notesRef` argument is the canonical name of the reference to use, + /// defaulting to "refs/notes/commits". + /// + /// The id specified is the Oid of the git object to read the note from. + /// + /// @category Repository/Methods + /// @signature + /// ```ts + /// class Repository { + /// findNote(id: string, options?: FindNoteOptions | null | undefined): Note | null; + /// } + /// ``` + /// + /// @param {string} id - OID of the git object to read the note from. + /// @param {FindNoteOptions} [options] - Options for finding note. + /// @returns Instance of the note. If does not exists, returns `null`. + pub fn find_note( + &self, + this: Reference, + env: Env, + id: String, + options: Option, + ) -> Option { + self.get_note(this, env, id, options).ok() + } + + #[napi] + /// Remove the note for an object. + /// + /// The `notesRef` argument is the canonical name of the reference to use, + /// defaulting to "refs/notes/commits". + /// + /// The id specified is the Oid of the git object to remove the note from. + /// + /// @category Repository/Methods + /// @signature + /// ```ts + /// class Repository { + /// deleteNote(id: string, options?: DeleteNoteOptions | null | undefined): void; + /// } + /// ``` + /// + /// @param {string} id - OID of the git object to remove the note from. + /// @param {DeleteNoteOptions} [options] - Options for deleting note. + pub fn delete_note(&self, id: String, options: Option) -> crate::Result<()> { + let opts = options.unwrap_or_default(); + let id = Oid::from_str(&id)?; + let author = opts + .author + .and_then(|x| Signature::try_from(x).ok()) + .and_then(|x| git2::Signature::try_from(x).ok()) + .or_else(|| self.inner.signature().ok()) + .ok_or(crate::Error::SignatureNotFound)?; + let committer = opts + .committer + .and_then(|x| Signature::try_from(x).ok()) + .and_then(|x| git2::Signature::try_from(x).ok()) + .or_else(|| self.inner.signature().ok()) + .ok_or(crate::Error::SignatureNotFound)?; + let notes_ref = opts.notes_ref; + self.inner.note_delete(id, notes_ref.as_deref(), &author, &committer)?; + Ok(()) + } +} From 5f54dfcd65682f1e541ecb1a05f067750813658d Mon Sep 17 00:00:00 2001 From: Seokju Na Date: Fri, 28 Nov 2025 21:09:34 +0900 Subject: [PATCH 2/5] add tests --- tests/note.spec.ts | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 tests/note.spec.ts diff --git a/tests/note.spec.ts b/tests/note.spec.ts new file mode 100644 index 0000000..2f7eb2c --- /dev/null +++ b/tests/note.spec.ts @@ -0,0 +1,56 @@ +import { describe, expect, it } from 'vitest'; +import { openRepository } from '../index'; +import { useFixture } from './fixtures'; + +describe('note', () => { + const signature = { + name: 'Seokju Na', + email: 'seokju.me@toss.im', + }; + + it('get default note ref', async () => { + const p = await useFixture('commits'); + const repo = await openRepository(p); + const ref = repo.noteDefaultRef(); + expect(ref).toEqual('refs/notes/commits'); + }); + + it('create note', async () => { + const p = await useFixture('commits'); + const repo = await openRepository(p); + const noteId = repo.note('a01e9888e46729ef4aa68953ba19b02a7a64eb82', 'this is note', { + author: signature, + committer: signature, + }); + const note = repo.getNote('a01e9888e46729ef4aa68953ba19b02a7a64eb82'); + expect(note.id()).toEqual(noteId); + expect(note.message()).toEqual('this is note'); + }); + + it('delete note', async () => { + const p = await useFixture('commits'); + const repo = await openRepository(p); + repo.note('a01e9888e46729ef4aa68953ba19b02a7a64eb82', 'this is note', { + author: signature, + committer: signature, + }); + expect(repo.findNote('a01e9888e46729ef4aa68953ba19b02a7a64eb82')).not.toBeNull(); + repo.deleteNote('a01e9888e46729ef4aa68953ba19b02a7a64eb82'); + expect(repo.findNote('a01e9888e46729ef4aa68953ba19b02a7a64eb82')).toBeNull(); + }); + + it('iterate notes', async () => { + const p = await useFixture('commits'); + const repo = await openRepository(p); + repo.note('a01e9888e46729ef4aa68953ba19b02a7a64eb82', 'note1', { + author: signature, + committer: signature, + }); + repo.note('b33e0101b828225f77eeff4dfa31259dcf379002', 'note2', { + author: signature, + committer: signature, + }); + const result = [...repo.notes()]; + expect(result).toHaveLength(2); + }); +}); From 35c71aa01491534d503ffbda913e10cbb4c68a09 Mon Sep 17 00:00:00 2001 From: Seokju Na Date: Fri, 28 Nov 2025 21:09:40 +0900 Subject: [PATCH 3/5] generated files --- index.d.ts | 264 +++++++++++++++++++++++++++++++++++++++++++++++++++++ index.js | 2 + 2 files changed, 266 insertions(+) diff --git a/index.d.ts b/index.d.ts index 8dd323f..4411307 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1895,6 +1895,85 @@ export declare class Mailmap { resolveSignature(signature: SignaturePayload): Signature } +/** + * A structure representing a [note][1] in git. + * + * [1]: http://alblue.bandlem.com/2011/11/git-tip-of-week-git-notes.html + */ +export declare class Note { + /** + * Get the note object's id + * + * @category Note/Methods + * @signature + * ```ts + * class Note { + * id(): string; + * } + * ``` + * + * @returns The note object's id. + */ + id(): string + /** + * Get the note author + * + * @category Note/Methods + * @signature + * ```ts + * class Note { + * author(): Signature; + * } + * ``` + * + * @returns The note author signature. + */ + author(): Signature + /** + * Get the note committer + * + * @category Note/Methods + * @signature + * ```ts + * class Note { + * committer(): Signature; + * } + * ``` + * + * @returns The note committer signature. + */ + committer(): Signature + /** + * Get the note message as a string. + * + * @category Note/Methods + * @signature + * ```ts + * class Note { + * message(): string; + * } + * ``` + * + * @returns The note message as a string + * @throws Throws error if message is not utf-8. + */ + message(): string +} + +/** + * An iterator over all of the notes within a repository. + * + * This type extends JavaScript's `Iterator`, and so has the iterator helper + * methods. It may extend the upcoming TypeScript `Iterator` class in the future. + * + * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator#iterator_helper_methods + * @see https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-6.html#iterator-helper-methods + */ +export declare class Notes extends Iterator { + + next(value?: void): IteratorResult +} + /** * Representation of a rebase * Begin the rebase by iterating the returned `Rebase` @@ -3218,6 +3297,134 @@ export declare class Repository { * @returns Merge analysis result. */ analyzeMergeForRef(ourRef: Reference, theirHeads: Array): MergeAnalysisResult + /** + * Add a note for an object + * + * The `notesRef` argument is the canonical name of the reference to use, + * defaulting to "refs/notes/commits". If `force` is specified then + * previous notes are overwritten. + * + * @category Repository/Methods + * @signature + * ```ts + * class Repository { + * note(oid: string, note: string, options?: CreateNoteOptions | null | undefined): string; + * } + * ``` + * + * @param {string} oid - OID of the git object to decorate. + * @param {string} note - Content of the note to add for object oid. + * @param {CreateNoteOptions} [options] - Options for creating note. + * @returns OID for the note. + */ + note(oid: string, note: string, options?: CreateNoteOptions | undefined | null): string + /** + * Get the default notes reference for this repository + * + * @category Repository/Methods + * @signature + * ```ts + * class Repository { + * noteDefaultRef(): string; + * } + * ``` + * + * @returns The default notes reference. + */ + noteDefaultRef(): string + /** + * Creates a new iterator for notes in this repository. + * + * The `notesRef` argument is the canonical name of the reference to use, + * defaulting to "refs/notes/commits". + * + * @category Repository/Methods + * @signature + * ```ts + * class Repository { + * notes(notesRef?: string | null | undefined): Notes; + * } + * ``` + * + * @param {string} [notesRef] - The canonical name of the reference to use. + * @returns Iterator of all notes. The iterator returned yields pairs of `[string, string]` + * where first element is the id of the note and the second id is the id the note is annotating. + * + * @example + * ```ts + * import { openRepository } from 'es-git'; + * + * const repo = await openRepository('.'); + * for (const { noteId, annotatedId } of repo.notes()) { + * const note = repo.getNote(noteId); + * const commit = repo.getCommit(annotatedId); + * } + * ``` + */ + notes(notesRef?: string | undefined | null): Notes + /** + * Read the note for an object. + * + * The `notesRef` argument is the canonical name of the reference to use, + * defaulting to "refs/notes/commits". + * + * The id specified is the Oid of the git object to read the note from. + * + * @category Repository/Methods + * @signature + * ```ts + * class Repository { + * getNote(id: string, options?: FindNoteOptions | null | undefined): Note; + * } + * ``` + * + * @param {string} id - OID of the git object to read the note from. + * @param {FindNoteOptions} [options] - Options for finding note. + * @returns Instance of the note. + * @throws Throws error if note does not exists. + */ + getNote(id: string, options?: FindNoteOptions | undefined | null): Note + /** + * Read the note for an object. + * + * The `notesRef` argument is the canonical name of the reference to use, + * defaulting to "refs/notes/commits". + * + * The id specified is the Oid of the git object to read the note from. + * + * @category Repository/Methods + * @signature + * ```ts + * class Repository { + * findNote(id: string, options?: FindNoteOptions | null | undefined): Note | null; + * } + * ``` + * + * @param {string} id - OID of the git object to read the note from. + * @param {FindNoteOptions} [options] - Options for finding note. + * @returns Instance of the note. If does not exists, returns `null`. + */ + findNote(id: string, options?: FindNoteOptions | undefined | null): Note | null + /** + * Remove the note for an object. + * + * The `notesRef` argument is the canonical name of the reference to use, + * defaulting to "refs/notes/commits". + * + * The id specified is the Oid of the git object to remove the note from. + * + * @category Repository/Methods + * @signature + * ```ts + * class Repository { + * deleteNote(id: string, options?: DeleteNoteOptions | null | undefined): void; + * } + * ``` + * + * @param {string} id - OID of the git object to remove the note from. + * @param {DeleteNoteOptions} [options] - Options for deleting note. + */ + deleteNote(id: string, options?: DeleteNoteOptions | undefined | null): void /** * Lookup a reference to one of the objects in a repository. * @@ -5734,6 +5941,31 @@ export interface CreateLightweightTagOptions { */ export declare function createMailmapFromBuffer(content: string): Mailmap +export interface CreateNoteOptions { + /** + * Signature of the notes commit author. + * + * If not provided, the default signature of the repository will be used. + * If there is no default signature set for the repository, an error will occur. + */ + author?: SignaturePayload + /** + * Signature of the notes commit commiter. + * + * If not provided, the default signature of the repository will be used. + * If there is no default signature set for the repository, an error will occur. + */ + committer?: SignaturePayload + /** + * canonical name of the reference to use. + * + * Defaults to "refs/notes/commits". + */ + notesRef?: string + /** Overwrite existing note. */ + force?: boolean +} + export interface CreateRemoteOptions { fetchRefspec?: string } @@ -5811,6 +6043,29 @@ export type CredentialType = 'Default'| 'SSHKey'| 'Plain'; +export interface DeleteNoteOptions { + /** + * Signature of the notes commit author. + * + * If not provided, the default signature of the repository will be used. + * If there is no default signature set for the repository, an error will occur. + */ + author?: SignaturePayload + /** + * Signature of the notes commit commiter. + * + * If not provided, the default signature of the repository will be used. + * If there is no default signature set for the repository, an error will occur. + */ + committer?: SignaturePayload + /** + * canonical name of the reference to use. + * + * Defaults to "refs/notes/commits". + */ + notesRef?: string +} + /** * - `Unmodified` : No changes. * - `Added` : Entry does not exist in an old version. @@ -6250,6 +6505,10 @@ export type FileMode = 'Unreadable'| */ export declare function findGlobalConfigPath(): string | null +export interface FindNoteOptions { + notesRef?: string +} + /** * Locate the path to the system configuration file. * @@ -6722,6 +6981,11 @@ export interface MergePreference { */ export declare function normalizeReferenceName(refname: string, format?: number | undefined | null): string | null +export interface NoteIterItem { + noteId: string + annotatedId: string +} + /** * - `Any` : Any kind of git object * - `Commit` : An object which corresponds to a git commit diff --git a/index.js b/index.js index 6aed265..360638c 100644 --- a/index.js +++ b/index.js @@ -591,6 +591,8 @@ module.exports.GitObject = nativeBinding.GitObject module.exports.Index = nativeBinding.Index module.exports.IndexEntries = nativeBinding.IndexEntries module.exports.Mailmap = nativeBinding.Mailmap +module.exports.Note = nativeBinding.Note +module.exports.Notes = nativeBinding.Notes module.exports.Rebase = nativeBinding.Rebase module.exports.Reference = nativeBinding.Reference module.exports.Remote = nativeBinding.Remote From 32948ba063c3600e1614ddeeb6ab04107969ebcb Mon Sep 17 00:00:00 2001 From: Seokju Na Date: Fri, 28 Nov 2025 21:09:43 +0900 Subject: [PATCH 4/5] add docs --- docs/ko/reference/Note/Methods/author.md | 38 ++++++ docs/ko/reference/Note/Methods/committer.md | 38 ++++++ docs/ko/reference/Note/Methods/id.md | 21 +++ docs/ko/reference/Note/Methods/message.md | 31 +++++ .../Repository/Methods/deleteNote.md | 104 +++++++++++++++ .../reference/Repository/Methods/findNote.md | 46 +++++++ .../reference/Repository/Methods/getNote.md | 57 ++++++++ docs/ko/reference/Repository/Methods/note.md | 123 ++++++++++++++++++ .../Repository/Methods/noteDefaultRef.md | 21 +++ docs/ko/reference/Repository/Methods/notes.md | 46 +++++++ docs/reference/Note/Methods/author.md | 38 ++++++ docs/reference/Note/Methods/committer.md | 38 ++++++ docs/reference/Note/Methods/id.md | 21 +++ docs/reference/Note/Methods/message.md | 31 +++++ .../Repository/Methods/deleteNote.md | 104 +++++++++++++++ docs/reference/Repository/Methods/findNote.md | 47 +++++++ docs/reference/Repository/Methods/getNote.md | 57 ++++++++ docs/reference/Repository/Methods/note.md | 123 ++++++++++++++++++ .../Repository/Methods/noteDefaultRef.md | 21 +++ docs/reference/Repository/Methods/notes.md | 46 +++++++ 20 files changed, 1051 insertions(+) create mode 100644 docs/ko/reference/Note/Methods/author.md create mode 100644 docs/ko/reference/Note/Methods/committer.md create mode 100644 docs/ko/reference/Note/Methods/id.md create mode 100644 docs/ko/reference/Note/Methods/message.md create mode 100644 docs/ko/reference/Repository/Methods/deleteNote.md create mode 100644 docs/ko/reference/Repository/Methods/findNote.md create mode 100644 docs/ko/reference/Repository/Methods/getNote.md create mode 100644 docs/ko/reference/Repository/Methods/note.md create mode 100644 docs/ko/reference/Repository/Methods/noteDefaultRef.md create mode 100644 docs/ko/reference/Repository/Methods/notes.md create mode 100644 docs/reference/Note/Methods/author.md create mode 100644 docs/reference/Note/Methods/committer.md create mode 100644 docs/reference/Note/Methods/id.md create mode 100644 docs/reference/Note/Methods/message.md create mode 100644 docs/reference/Repository/Methods/deleteNote.md create mode 100644 docs/reference/Repository/Methods/findNote.md create mode 100644 docs/reference/Repository/Methods/getNote.md create mode 100644 docs/reference/Repository/Methods/note.md create mode 100644 docs/reference/Repository/Methods/noteDefaultRef.md create mode 100644 docs/reference/Repository/Methods/notes.md diff --git a/docs/ko/reference/Note/Methods/author.md b/docs/ko/reference/Note/Methods/author.md new file mode 100644 index 0000000..8d57cb7 --- /dev/null +++ b/docs/ko/reference/Note/Methods/author.md @@ -0,0 +1,38 @@ +# author + +노트 작성자를 가져와요 + +## 시그니처 + +```ts +class Note { + author(): Signature; +} +``` + +### 반환 값 + +
    +
  • + Signature +
    +

    노트 작성자 서명 정보

    +
      +
    • + email필수 · string +
      +

      서명에 사용된 이메일 주소

      +
    • +
    • + name필수 · string +
      +

      서명에 사용된 이름

      +
    • +
    • + timestamp필수 · number +
      +

      Epoch 기준 초 단위 시간

      +
    • +
    +
  • +
\ No newline at end of file diff --git a/docs/ko/reference/Note/Methods/committer.md b/docs/ko/reference/Note/Methods/committer.md new file mode 100644 index 0000000..e47feba --- /dev/null +++ b/docs/ko/reference/Note/Methods/committer.md @@ -0,0 +1,38 @@ +# committer + +노트 커미터를 가져와요 + +## 시그니처 + +```ts +class Note { + committer(): Signature; +} +``` + +### 반환 값 + +
    +
  • + Signature +
    +

    노트 커미터 서명 정보예요

    +
      +
    • + email필수 · string +
      +

      서명에 사용된 이메일이에요

      +
    • +
    • + name필수 · string +
      +

      서명에 사용된 이름이에요

      +
    • +
    • + timestamp필수 · number +
      +

      epoch 기준 초 단위 시간이에요

      +
    • +
    +
  • +
\ No newline at end of file diff --git a/docs/ko/reference/Note/Methods/id.md b/docs/ko/reference/Note/Methods/id.md new file mode 100644 index 0000000..562328f --- /dev/null +++ b/docs/ko/reference/Note/Methods/id.md @@ -0,0 +1,21 @@ +# id + +노트 개체의 id를 가져와요 + +## 시그니처 + +```ts +class Note { + id(): string; +} +``` + +### 반환 값 + +
    +
  • + string +
    +

    노트 개체의 id 값

    +
  • +
\ No newline at end of file diff --git a/docs/ko/reference/Note/Methods/message.md b/docs/ko/reference/Note/Methods/message.md new file mode 100644 index 0000000..84d78f5 --- /dev/null +++ b/docs/ko/reference/Note/Methods/message.md @@ -0,0 +1,31 @@ +# message + +노트 메시지를 문자열로 가져와요. + +## 시그니처 + +```ts +class Note { + message(): string; +} +``` + +### 반환 값 + +
    +
  • + string +
    +

    문자열인 노트 메시지

    +
  • +
+ +### 에러 + +
    +
  • + Error +
    +

    메시지가 utf-8이 아니면 오류를 던져요.

    +
  • +
\ No newline at end of file diff --git a/docs/ko/reference/Repository/Methods/deleteNote.md b/docs/ko/reference/Repository/Methods/deleteNote.md new file mode 100644 index 0000000..92ee49f --- /dev/null +++ b/docs/ko/reference/Repository/Methods/deleteNote.md @@ -0,0 +1,104 @@ +# deleteNote + +개체에 대한 노트를 제거해요. + +`notesRef` 인수는 사용할 참조의 정규 이름이에요. +기본값은 "refs/notes/commits"예요. + +지정된 id는 노트를 제거할 Git 개체의 Oid예요. + +## 시그니처 + +```ts +class Repository { + deleteNote(id: string, options?: DeleteNoteOptions | null | undefined): void; +} +``` + +### 파라미터 + +
    +
  • + id필수 · string +
    +

    노트를 제거할 Git 개체의 OID예요.

    +
  • +
  • + optionsnull | DeleteNoteOptions +
    +

    노트를 삭제하기 위한 옵션이에요.

    +
      +
    • + authorSignaturePayload +
      +

      노트 커밋 작성자의 서명이에요. 제공하지 않으면 리포지토리의 기본 서명을 사용해요. 리포지토리에 기본 서명이 설정되어 있지 않으면 오류가 발생해요.

      +
        +
      • + email필수 · string +
        +

        서명에 사용되는 이메일이에요.

        +
      • +
      • + name필수 · string +
        +

        서명에 사용되는 이름이에요.

        +
      • +
      • + timeOptionsSignatureTimeOptions +
        +
          +
        • + offsetnumber +
          +

          시간대 오프셋(분 단위)이에요.

          +
        • +
        • + timestamp필수 · number +
          +

          에포크 기준 초 단위 시간이에요.

          +
        • +
        +
      • +
      +
    • +
    • + committerSignaturePayload +
      +

      노트 커밋 커미터의 서명이에요. 제공하지 않으면 리포지토리의 기본 서명을 사용해요. 리포지토리에 기본 서명이 설정되어 있지 않으면 오류가 발생해요.

      +
        +
      • + email필수 · string +
        +

        서명에 사용되는 이메일이에요.

        +
      • +
      • + name필수 · string +
        +

        서명에 사용되는 이름이에요.

        +
      • +
      • + timeOptionsSignatureTimeOptions +
        +
          +
        • + offsetnumber +
          +

          시간대 오프셋(분 단위)이에요.

          +
        • +
        • + timestamp필수 · number +
          +

          에포크 기준 초 단위 시간이에요.

          +
        • +
        +
      • +
      +
    • +
    • + notesRefstring +
      +

      사용할 참조의 정규 이름이에요. 기본값은 "refs/notes/commits"예요.

      +
    • +
    +
  • +
\ No newline at end of file diff --git a/docs/ko/reference/Repository/Methods/findNote.md b/docs/ko/reference/Repository/Methods/findNote.md new file mode 100644 index 0000000..21fb701 --- /dev/null +++ b/docs/ko/reference/Repository/Methods/findNote.md @@ -0,0 +1,46 @@ +# findNote + +개체에 대한 노트를 읽어요. + +`notesRef` 인수는 사용할 기준 참조 이름이고, 기본값은 "refs/notes/commits"예요. + +지정된 id는 노트를 읽을 Git 개체의 Oid예요. + +## 시그니처 + +```ts +class Repository { + findNote(id: string, options?: FindNoteOptions | null | undefined): Note | null; +} +``` + +### 파라미터 + +
    +
  • + id필수 · string +
    +

    노트를 읽을 Git 개체의 OID 값

    +
  • +
  • + optionsnull | FindNoteOptions +
    +

    노트를 찾을 때 사용할 옵션

    +
      +
    • + notesRefstring +
      +
    • +
    +
  • +
+ +### 반환 값 + +
    +
  • + null | Note +
    +

    노트 인스턴스. 존재하지 않으면 null을 반환하는 값

    +
  • +
\ No newline at end of file diff --git a/docs/ko/reference/Repository/Methods/getNote.md b/docs/ko/reference/Repository/Methods/getNote.md new file mode 100644 index 0000000..63e0429 --- /dev/null +++ b/docs/ko/reference/Repository/Methods/getNote.md @@ -0,0 +1,57 @@ +# getNote + +개체에 대한 노트를 읽어요. + +`notesRef` 인수는 사용할 참조의 정식 이름이에요. +기본값은 "refs/notes/commits"예요. + +지정된 id는 노트를 읽을 Git 개체의 Oid예요. + +## 시그니처 + +```ts +class Repository { + getNote(id: string, options?: FindNoteOptions | null | undefined): Note; +} +``` + +### 파라미터 + +
    +
  • + id필수 · string +
    +

    노트를 읽을 Git 개체의 OID예요.

    +
  • +
  • + optionsnull | FindNoteOptions +
    +

    노트를 찾기 위한 옵션이에요.

    +
      +
    • + notesRefstring +
      +
    • +
    +
  • +
+ +### 반환 값 + +
    +
  • + Note +
    +

    노트의 인스턴스예요.

    +
  • +
+ +### 에러 + +
    +
  • + Error +
    +

    노트가 존재하지 않으면 에러를 던져요.

    +
  • +
\ No newline at end of file diff --git a/docs/ko/reference/Repository/Methods/note.md b/docs/ko/reference/Repository/Methods/note.md new file mode 100644 index 0000000..6b16ca4 --- /dev/null +++ b/docs/ko/reference/Repository/Methods/note.md @@ -0,0 +1,123 @@ +# note + +개체에 대한 노트를 추가해요 + +`notesRef` 인수는 사용할 참조의 정규 이름이에요. +지정하지 않으면 기본값은 "refs/notes/commits"예요. `force`가 지정되면 +이전에 존재하던 노트가 덮어써져요. + +## 시그니처 + +```ts +class Repository { + note(oid: string, note: string, options?: CreateNoteOptions | null | undefined): string; +} +``` + +### 파라미터 + +
    +
  • + oid필수 · string +
    +

    장식할 Git 개체의 OID 값이에요.

    +
  • +
  • + note필수 · string +
    +

    해당 개체 OID에 추가할 노트의 내용이에요.

    +
  • +
  • + optionsnull | CreateNoteOptions +
    +

    노트를 생성하기 위한 옵션이에요.

    +
      +
    • + authorSignaturePayload +
      +

      노트 커밋 작성자의 서명이에요. 제공되지 않으면 리포지토리의 기본 서명을 사용해요. 리포지토리에 기본 서명이 설정되어 있지 않으면 오류가 발생해요.

      +
        +
      • + email필수 · string +
        +

        서명에 사용되는 이메일이에요.

        +
      • +
      • + name필수 · string +
        +

        서명에 사용되는 이름이에요.

        +
      • +
      • + timeOptionsSignatureTimeOptions +
        +
          +
        • + offsetnumber +
          +

          시간대 오프셋(분 단위)이에요.

          +
        • +
        • + timestamp필수 · number +
          +

          Unix epoch 기준 초 단위 시간이에요.

          +
        • +
        +
      • +
      +
    • +
    • + committerSignaturePayload +
      +

      노트 커밋 커미터의 서명이에요. 제공되지 않으면 리포지토리의 기본 서명을 사용해요. 리포지토리에 기본 서명이 설정되어 있지 않으면 오류가 발생해요.

      +
        +
      • + email필수 · string +
        +

        서명에 사용되는 이메일이에요.

        +
      • +
      • + name필수 · string +
        +

        서명에 사용되는 이름이에요.

        +
      • +
      • + timeOptionsSignatureTimeOptions +
        +
          +
        • + offsetnumber +
          +

          시간대 오프셋(분 단위)이에요.

          +
        • +
        • + timestamp필수 · number +
          +

          Unix epoch 기준 초 단위 시간이에요.

          +
        • +
        +
      • +
      +
    • +
    • + forceboolean +
      +

      기존 노트를 덮어쓸지 여부예요.

      +
    • +
    • + notesRefstring +
      +

      사용할 참조의 정규 이름이에요. 기본값은 "refs/notes/commits"예요.

      +
    • +
    +
  • +
+ +### 반환 값 + +
    +
  • + string +
    +

    노트의 OID 값이에요.

    +
  • +
\ No newline at end of file diff --git a/docs/ko/reference/Repository/Methods/noteDefaultRef.md b/docs/ko/reference/Repository/Methods/noteDefaultRef.md new file mode 100644 index 0000000..eef4000 --- /dev/null +++ b/docs/ko/reference/Repository/Methods/noteDefaultRef.md @@ -0,0 +1,21 @@ +# noteDefaultRef + +이 리포지토리의 기본 노트 참조를 가져와요 + +## 시그니처 + +```ts +class Repository { + noteDefaultRef(): string; +} +``` + +### 반환 값 + +
    +
  • + string +
    +

    기본 노트 참조 이름

    +
  • +
\ No newline at end of file diff --git a/docs/ko/reference/Repository/Methods/notes.md b/docs/ko/reference/Repository/Methods/notes.md new file mode 100644 index 0000000..bac156e --- /dev/null +++ b/docs/ko/reference/Repository/Methods/notes.md @@ -0,0 +1,46 @@ +# notes + +이 리포지토리에서 노트용 새 이터레이터를 만들어요. + +`notesRef` 인수는 사용할 참조의 표준 이름이고, +기본값은 "refs/notes/commits"예요. + +## 시그니처 + +```ts +class Repository { + notes(notesRef?: string | null | undefined): Notes; +} +``` + +### 파라미터 + +
    +
  • + notesRefnull | string +
    +

    사용할 참조의 표준 이름이에요.

    +
  • +
+ +### 반환 값 + +
    +
  • + Notes +
    +

    모든 노트에 대한 이터레이터예요. 반환된 이터레이터는 [string, string]
    쌍을 순서대로 제공하고, 첫 번째 요소는 노트의 ID이고 두 번째 요소는 그 노트가 주석을 다는 대상의 ID예요.

    +
  • +
+ +## 예제 + +```ts +import { openRepository } from 'es-git'; + +const repo = await openRepository('.'); +for (const { noteId, annotatedId } of repo.notes()) { + const note = repo.getNote(noteId); + const commit = repo.getCommit(annotatedId); +} +``` \ No newline at end of file diff --git a/docs/reference/Note/Methods/author.md b/docs/reference/Note/Methods/author.md new file mode 100644 index 0000000..c14a98c --- /dev/null +++ b/docs/reference/Note/Methods/author.md @@ -0,0 +1,38 @@ +# author + +Get the note author + +## Signature + +```ts +class Note { + author(): Signature; +} +``` + +### Returns + +
    +
  • + Signature +
    +

    The note author signature.

    +
      +
    • + emailrequired · string +
      +

      Email on the signature.

      +
    • +
    • + namerequired · string +
      +

      Name on the signature.

      +
    • +
    • + timestamprequired · number +
      +

      Time in seconds, from epoch

      +
    • +
    +
  • +
\ No newline at end of file diff --git a/docs/reference/Note/Methods/committer.md b/docs/reference/Note/Methods/committer.md new file mode 100644 index 0000000..eb56008 --- /dev/null +++ b/docs/reference/Note/Methods/committer.md @@ -0,0 +1,38 @@ +# committer + +Get the note committer + +## Signature + +```ts +class Note { + committer(): Signature; +} +``` + +### Returns + +
    +
  • + Signature +
    +

    The note committer signature.

    +
      +
    • + emailrequired · string +
      +

      Email on the signature.

      +
    • +
    • + namerequired · string +
      +

      Name on the signature.

      +
    • +
    • + timestamprequired · number +
      +

      Time in seconds, from epoch

      +
    • +
    +
  • +
\ No newline at end of file diff --git a/docs/reference/Note/Methods/id.md b/docs/reference/Note/Methods/id.md new file mode 100644 index 0000000..3870abe --- /dev/null +++ b/docs/reference/Note/Methods/id.md @@ -0,0 +1,21 @@ +# id + +Get the note object's id + +## Signature + +```ts +class Note { + id(): string; +} +``` + +### Returns + +
    +
  • + string +
    +

    The note object's id.

    +
  • +
\ No newline at end of file diff --git a/docs/reference/Note/Methods/message.md b/docs/reference/Note/Methods/message.md new file mode 100644 index 0000000..fb43e9d --- /dev/null +++ b/docs/reference/Note/Methods/message.md @@ -0,0 +1,31 @@ +# message + +Get the note message as a string. + +## Signature + +```ts +class Note { + message(): string; +} +``` + +### Returns + +
    +
  • + string +
    +

    The note message as a string

    +
  • +
+ +### Errors + +
    +
  • + Error +
    +

    Throws error if message is not utf-8.

    +
  • +
\ No newline at end of file diff --git a/docs/reference/Repository/Methods/deleteNote.md b/docs/reference/Repository/Methods/deleteNote.md new file mode 100644 index 0000000..7c21630 --- /dev/null +++ b/docs/reference/Repository/Methods/deleteNote.md @@ -0,0 +1,104 @@ +# deleteNote + +Remove the note for an object. + +The `notesRef` argument is the canonical name of the reference to use, +defaulting to "refs/notes/commits". + +The id specified is the Oid of the git object to remove the note from. + +## Signature + +```ts +class Repository { + deleteNote(id: string, options?: DeleteNoteOptions | null | undefined): void; +} +``` + +### Parameters + +
    +
  • + idrequired · string +
    +

    OID of the git object to remove the note from.

    +
  • +
  • + optionsnull | DeleteNoteOptions +
    +

    Options for deleting note.

    +
      +
    • + authorSignaturePayload +
      +

      Signature of the notes commit author. If not provided, the default signature of the repository will be used. If there is no default signature set for the repository, an error will occur.

      +
        +
      • + emailrequired · string +
        +

        Email on the signature.

        +
      • +
      • + namerequired · string +
        +

        Name on the signature.

        +
      • +
      • + timeOptionsSignatureTimeOptions +
        +
          +
        • + offsetnumber +
          +

          Timezone offset, in minutes

          +
        • +
        • + timestamprequired · number +
          +

          Time in seconds, from epoch

          +
        • +
        +
      • +
      +
    • +
    • + committerSignaturePayload +
      +

      Signature of the notes commit commiter. If not provided, the default signature of the repository will be used. If there is no default signature set for the repository, an error will occur.

      +
        +
      • + emailrequired · string +
        +

        Email on the signature.

        +
      • +
      • + namerequired · string +
        +

        Name on the signature.

        +
      • +
      • + timeOptionsSignatureTimeOptions +
        +
          +
        • + offsetnumber +
          +

          Timezone offset, in minutes

          +
        • +
        • + timestamprequired · number +
          +

          Time in seconds, from epoch

          +
        • +
        +
      • +
      +
    • +
    • + notesRefstring +
      +

      canonical name of the reference to use. Defaults to "refs/notes/commits".

      +
    • +
    +
  • +
\ No newline at end of file diff --git a/docs/reference/Repository/Methods/findNote.md b/docs/reference/Repository/Methods/findNote.md new file mode 100644 index 0000000..30c2c27 --- /dev/null +++ b/docs/reference/Repository/Methods/findNote.md @@ -0,0 +1,47 @@ +# findNote + +Read the note for an object. + +The `notesRef` argument is the canonical name of the reference to use, +defaulting to "refs/notes/commits". + +The id specified is the Oid of the git object to read the note from. + +## Signature + +```ts +class Repository { + findNote(id: string, options?: FindNoteOptions | null | undefined): Note | null; +} +``` + +### Parameters + +
    +
  • + idrequired · string +
    +

    OID of the git object to read the note from.

    +
  • +
  • + optionsnull | FindNoteOptions +
    +

    Options for finding note.

    +
      +
    • + notesRefstring +
      +
    • +
    +
  • +
+ +### Returns + +
    +
  • + null | Note +
    +

    Instance of the note. If does not exists, returns null .

    +
  • +
\ No newline at end of file diff --git a/docs/reference/Repository/Methods/getNote.md b/docs/reference/Repository/Methods/getNote.md new file mode 100644 index 0000000..a7a4c97 --- /dev/null +++ b/docs/reference/Repository/Methods/getNote.md @@ -0,0 +1,57 @@ +# getNote + +Read the note for an object. + +The `notesRef` argument is the canonical name of the reference to use, +defaulting to "refs/notes/commits". + +The id specified is the Oid of the git object to read the note from. + +## Signature + +```ts +class Repository { + getNote(id: string, options?: FindNoteOptions | null | undefined): Note; +} +``` + +### Parameters + +
    +
  • + idrequired · string +
    +

    OID of the git object to read the note from.

    +
  • +
  • + optionsnull | FindNoteOptions +
    +

    Options for finding note.

    +
      +
    • + notesRefstring +
      +
    • +
    +
  • +
+ +### Returns + +
    +
  • + Note +
    +

    Instance of the note.

    +
  • +
+ +### Errors + +
    +
  • + Error +
    +

    Throws error if note does not exists.

    +
  • +
\ No newline at end of file diff --git a/docs/reference/Repository/Methods/note.md b/docs/reference/Repository/Methods/note.md new file mode 100644 index 0000000..84261dd --- /dev/null +++ b/docs/reference/Repository/Methods/note.md @@ -0,0 +1,123 @@ +# note + +Add a note for an object + +The `notesRef` argument is the canonical name of the reference to use, +defaulting to "refs/notes/commits". If `force` is specified then +previous notes are overwritten. + +## Signature + +```ts +class Repository { + note(oid: string, note: string, options?: CreateNoteOptions | null | undefined): string; +} +``` + +### Parameters + +
    +
  • + oidrequired · string +
    +

    OID of the git object to decorate.

    +
  • +
  • + noterequired · string +
    +

    Content of the note to add for object oid.

    +
  • +
  • + optionsnull | CreateNoteOptions +
    +

    Options for creating note.

    +
      +
    • + authorSignaturePayload +
      +

      Signature of the notes commit author. If not provided, the default signature of the repository will be used. If there is no default signature set for the repository, an error will occur.

      +
        +
      • + emailrequired · string +
        +

        Email on the signature.

        +
      • +
      • + namerequired · string +
        +

        Name on the signature.

        +
      • +
      • + timeOptionsSignatureTimeOptions +
        +
          +
        • + offsetnumber +
          +

          Timezone offset, in minutes

          +
        • +
        • + timestamprequired · number +
          +

          Time in seconds, from epoch

          +
        • +
        +
      • +
      +
    • +
    • + committerSignaturePayload +
      +

      Signature of the notes commit commiter. If not provided, the default signature of the repository will be used. If there is no default signature set for the repository, an error will occur.

      +
        +
      • + emailrequired · string +
        +

        Email on the signature.

        +
      • +
      • + namerequired · string +
        +

        Name on the signature.

        +
      • +
      • + timeOptionsSignatureTimeOptions +
        +
          +
        • + offsetnumber +
          +

          Timezone offset, in minutes

          +
        • +
        • + timestamprequired · number +
          +

          Time in seconds, from epoch

          +
        • +
        +
      • +
      +
    • +
    • + forceboolean +
      +

      Overwrite existing note.

      +
    • +
    • + notesRefstring +
      +

      canonical name of the reference to use. Defaults to "refs/notes/commits".

      +
    • +
    +
  • +
+ +### Returns + +
    +
  • + string +
    +

    OID for the note.

    +
  • +
\ No newline at end of file diff --git a/docs/reference/Repository/Methods/noteDefaultRef.md b/docs/reference/Repository/Methods/noteDefaultRef.md new file mode 100644 index 0000000..7e29023 --- /dev/null +++ b/docs/reference/Repository/Methods/noteDefaultRef.md @@ -0,0 +1,21 @@ +# noteDefaultRef + +Get the default notes reference for this repository + +## Signature + +```ts +class Repository { + noteDefaultRef(): string; +} +``` + +### Returns + +
    +
  • + string +
    +

    The default notes reference.

    +
  • +
\ No newline at end of file diff --git a/docs/reference/Repository/Methods/notes.md b/docs/reference/Repository/Methods/notes.md new file mode 100644 index 0000000..b35ae59 --- /dev/null +++ b/docs/reference/Repository/Methods/notes.md @@ -0,0 +1,46 @@ +# notes + +Creates a new iterator for notes in this repository. + +The `notesRef` argument is the canonical name of the reference to use, +defaulting to "refs/notes/commits". + +## Signature + +```ts +class Repository { + notes(noteRef?: string | null | undefined): Notes; +} +``` + +### Parameters + +
    +
  • + notesRefnull | string +
    +
  • +
+ +### Returns + +
    +
  • + Notes +
    +

    Iterator of all notes. The iterator returned yields pairs of [string, string]
    where first element is the id of the note and the second id is the id the note is annotating.

    +
  • +
+ +## Examples + +```ts +import { openRepository } from 'es-git'; + +const repo = await openRepository('.'); +for (const value of repo.notes()) { + const [noteId, annotatedId] = value; + const note = repo.getNote(noteId); + const commit = repo.getCommit(annotatedId); +} +``` \ No newline at end of file From 8a37e546623aa77bd3c39a3b6671f4583d02064c Mon Sep 17 00:00:00 2001 From: Seokju Na Date: Fri, 28 Nov 2025 21:19:47 +0900 Subject: [PATCH 5/5] fix --- tests/note.spec.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/note.spec.ts b/tests/note.spec.ts index 2f7eb2c..cd26a91 100644 --- a/tests/note.spec.ts +++ b/tests/note.spec.ts @@ -35,7 +35,10 @@ describe('note', () => { committer: signature, }); expect(repo.findNote('a01e9888e46729ef4aa68953ba19b02a7a64eb82')).not.toBeNull(); - repo.deleteNote('a01e9888e46729ef4aa68953ba19b02a7a64eb82'); + repo.deleteNote('a01e9888e46729ef4aa68953ba19b02a7a64eb82', { + author: signature, + committer: signature, + }); expect(repo.findNote('a01e9888e46729ef4aa68953ba19b02a7a64eb82')).toBeNull(); });