{"id":15768018,"url":"https://github.com/technote-space/vo-entity-ts","last_synced_at":"2026-03-04T02:33:15.013Z","repository":{"id":42391878,"uuid":"475450812","full_name":"technote-space/vo-entity-ts","owner":"technote-space","description":null,"archived":false,"fork":false,"pushed_at":"2025-05-27T10:44:34.000Z","size":968,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-24T01:56:10.011Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/technote-space.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"custom":"https://paypal.me/technote0space"}},"created_at":"2022-03-29T13:16:21.000Z","updated_at":"2025-05-27T10:44:27.000Z","dependencies_parsed_at":"2023-11-29T02:33:04.482Z","dependency_job_id":"139b8726-2374-4352-aea8-bb5186c4ece5","html_url":"https://github.com/technote-space/vo-entity-ts","commit_stats":{"total_commits":55,"total_committers":2,"mean_commits":27.5,"dds":"0.49090909090909096","last_synced_commit":"1281476bb88341b2a17170f644d9ba3193727936"},"previous_names":[],"tags_count":39,"template":false,"template_full_name":"technote-space/ts-package-template","purl":"pkg:github/technote-space/vo-entity-ts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technote-space%2Fvo-entity-ts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technote-space%2Fvo-entity-ts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technote-space%2Fvo-entity-ts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technote-space%2Fvo-entity-ts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/technote-space","download_url":"https://codeload.github.com/technote-space/vo-entity-ts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/technote-space%2Fvo-entity-ts/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30070122,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T01:03:42.280Z","status":"online","status_checked_at":"2026-03-04T02:00:07.464Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-04T13:42:08.963Z","updated_at":"2026-03-04T02:33:14.985Z","avatar_url":"https://github.com/technote-space.png","language":"TypeScript","funding_links":["https://paypal.me/technote0space"],"categories":[],"sub_categories":[],"readme":"# Vo Entity Ts\n\n[![npm version](https://badge.fury.io/js/%40technote-space%2Fvo-entity-ts.svg)](https://badge.fury.io/js/%40technote-space%2Fvo-entity-ts)\n[![CI Status](https://github.com/technote-space/vo-entity-ts/workflows/CI/badge.svg)](https://github.com/technote-space/vo-entity-ts/actions)\n[![codecov](https://codecov.io/gh/technote-space/vo-entity-ts/branch/master/graph/badge.svg)](https://codecov.io/gh/technote-space/vo-entity-ts)\n[![CodeFactor](https://www.codefactor.io/repository/github/technote-space/vo-entity-ts/badge)](https://www.codefactor.io/repository/github/technote-space/vo-entity-ts)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/technote-space/vo-entity-ts/blob/master/LICENSE)\n\n## Table of Contents\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\u003cdetails\u003e\n\u003csummary\u003eDetails\u003c/summary\u003e\n\n- [Setup](#setup)\n  - [yarn](#yarn)\n  - [npm](#npm)\n- [Author](#author)\n- [特徴](#%E7%89%B9%E5%BE%B4)\n- [Value Object](#value-object)\n  - [使用例](#%E4%BD%BF%E7%94%A8%E4%BE%8B)\n  - [その他の使用例](#%E3%81%9D%E3%81%AE%E4%BB%96%E3%81%AE%E4%BD%BF%E7%94%A8%E4%BE%8B)\n- [Entity](#entity)\n  - [使用例](#%E4%BD%BF%E7%94%A8%E4%BE%8B-1)\n- [コレクション](#%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3)\n- [ライセンス](#%E3%83%A9%E3%82%A4%E3%82%BB%E3%83%B3%E3%82%B9)\n- [開発](#%E9%96%8B%E7%99%BA)\n\n\u003c/details\u003e\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Setup\n### yarn\n- `yarn add @technote-space/vo-entity-ts`\n### npm\n- `npm i @technote-space/vo-entity-ts`\n\n## Author\n[GitHub (Technote)](https://github.com/technote-space)  \n[Blog](https://technote.space)\n\n## 特徴\n\n- Value Object と Entity の基本クラスを提供\n- 型安全な実装\n- バリデーション機能\n- イミュータブルな値の取り扱い\n- コレクションのサポート\n\n## Value Object\n\nValue Object は不変な値オブジェクトを表現するための基本クラスです。以下のような Value Object が提供されています：\n\n- `DateObject`: 日付を表現する Value Object\n- `Flags`: フラグを表現する Value Object\n- `Float`: 浮動小数点数を表現する Value Object\n- `Int`: 整数を表現する Value Object\n- `ObjectValue`: オブジェクトを表現する Value Object\n- `Phone`: 電話番号を表現する Value Object\n- `StringId`: 文字列IDを表現する Value Object\n- `Text`: テキストを表現する Value Object\n- `Url`: URLを表現する Value Object\n- `Email`: メールアドレスを表現する Value Object\n\n### 使用例\n\n```typescript\nimport { Text, Email, ObjectValue } from 'vo-entity-ts';\n\nclass UserName extends Text {\n  protected get symbol() {\n    return Symbol();\n  }\n\n  protected override getValidationMinLength(): number | undefined {\n    return 3;\n  }\n}\n\nclass UserEmail extends Email {\n  protected get symbol() {\n    return Symbol();\n  }\n}\n\n// 使用例\nconst name1 = new UserName('John');\nconst name2 = new UserName('Jane');\nconst shortName = new UserName('Jo');\n\n// 比較\nname1.equals(name2); // false\nname1.equals(new UserName('John')); // true\n\n// 値の取得\nname1.value; // 'John'\n\n// バリデーション\nname1.getErrors('name'); // undefined\nshortName.getErrors('name'); // [{ name: 'name', error: '3文字より長く入力してください' }]\n\n// イミュータブルな値\nconst name = name1.value;\nname = 'New Name'; // エラー: Cannot assign to 'name' because it is a read-only property\n```\n\n### その他の使用例\n\n各 Value Object のより詳細な使用例や実装パターンについては、以下のテストファイルを参照してください：\n\n- **基本的な使用方法**: [`src/valueObject/index.spec.ts`](src/valueObject/index.spec.ts)\n- **Text**: [`src/valueObject/text.spec.ts`](src/valueObject/text.spec.ts)\n- **Email**: [`src/valueObject/email.test.ts`](src/valueObject/email.test.ts)\n- **Url**: [`src/valueObject/url.test.ts`](src/valueObject/url.test.ts)\n- **Int**: [`src/valueObject/int.spec.ts`](src/valueObject/int.spec.ts)\n- **Float**: [`src/valueObject/float.spec.ts`](src/valueObject/float.spec.ts)\n- **DateObject**: [`src/valueObject/date.spec.ts`](src/valueObject/date.spec.ts)\n- **Flags**: [`src/valueObject/flags.spec.ts`](src/valueObject/flags.spec.ts)\n- **StringId**: [`src/valueObject/stringId.spec.ts`](src/valueObject/stringId.spec.ts)\n- **ObjectValue**: [`src/valueObject/object.spec.ts`](src/valueObject/object.spec.ts)\n- **Phone**: [`src/valueObject/phone.spec.ts`](src/valueObject/phone.spec.ts)\n- **Collection**: [`src/valueObject/collection.spec.ts`](src/valueObject/collection.spec.ts)\n- **Entity**: [`src/entity/index.spec.ts`](src/entity/index.spec.ts)\n\nこれらのテストファイルには、実際の使用例、エラーハンドリング、エッジケースの処理方法などが含まれています。\n\n## Entity\n\nEntity は識別子を持ち、ライフサイクルを通じて同一性を維持するオブジェクトを表現するための基本クラスです。\n\nEntity を実装する際は、`_create`、`_reconstruct`、`_update` メソッドに対して、実装する Entity の型（例：`User`）をジェネリクスの型パラメータとして渡すことが重要です：\n```typescript\n// 正しい使用法\npublic static create(...): User {\n  return User._create\u003cUser\u003e({ ... });\n}\n\npublic static reconstruct(...): User {\n  return User._reconstruct\u003cUser\u003e({ ... });\n}\n\npublic update(...): User {\n  return User._update\u003cUser\u003e(this, { ... });\n}\n```\n\n### 使用例\n\n```typescript\nimport { Entity, Text } from 'vo-entity-ts';\n\nclass User extends Entity {\n  protected constructor(props: {\n    name: UserName;\n    email: UserEmail;\n    status?: UserStatus;\n  }) {\n    super(props);\n  }\n\n  public static create(name: UserName, email: UserEmail): User {\n    return User._create\u003cUser\u003e({ name, email });\n  }\n\n  public static reconstruct(\n    name: UserName,\n    email: UserEmail,\n    status?: UserStatus,\n  ): User {\n    return User._reconstruct\u003cUser\u003e({ name, email, status });\n  }\n\n  public update({ status }: { status?: UserStatus }): User {\n    return User._update\u003cUser\u003e(this, { status });\n  }\n\n  public equals(other: User): boolean {\n    return this.get('email').equals(other.get('email'));\n  }\n}\n\n// 使用例\n// 新規作成\nconst name = new UserName('John Doe');\nconst email = new UserEmail('john@example.com');\nconst user = User.create(name, email);\n\n// 再構築（バリデーションをスキップ）\nconst status = new UserStatus('active');\nconst reconstructedUser = User.reconstruct(name, email, status);\n\n// 更新\nconst newStatus = new UserStatus('inactive');\nconst updatedUser = user.update({ status: newStatus });\n\n// プロパティの取得\nuser.get('name').value; // 'John Doe'\nuser.get('email').value; // 'john@example.com'\nuser.get('status')?.value; // undefined\n\n// 比較\nuser.equals(updatedUser); // true（email が同じため）\nuser.equals(User.create(new UserName('Jane Doe'), new UserEmail('jane@example.com'))); // false\n\n// バリデーションエラー\ntry {\n  User.create(\n    new UserName('Jo'),\n    new UserEmail('invalid-email')\n  );\n} catch (error) {\n  if (error instanceof ValidationException) {\n    console.log(error.errors);\n    // {\n    //   name: ['3文字より長く入力してください'],\n    //   email: ['有効なメールアドレスを指定してください']\n    // }\n  }\n}\n```\n\n## コレクション\n\nValueObject のコレクションを扱うための `Collection` クラスが提供されています。\n\n```typescript\nimport { Collection } from 'vo-entity-ts';\n\nclass UserEmails extends Collection\u003cUserEmail\u003e {\n  // カスタムのコレクション実装\n}\n```\n\n## ライセンス\n\nMIT\n\n## 開発\n\n```bash\n# 依存関係のインストール\nnpm install\n\n# テストの実行\nnpm test\n\n# ビルド\nnpm run build\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechnote-space%2Fvo-entity-ts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftechnote-space%2Fvo-entity-ts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftechnote-space%2Fvo-entity-ts/lists"}