@opentask/taskin-task-manager 2.0.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +237 -0
  2. package/dist/index.d.ts +4 -3
  3. package/dist/index.js +4 -3
  4. package/dist/index.js.map +1 -1
  5. package/dist/metrics.types.d.ts +64 -73
  6. package/dist/provider-stats.test.js.map +1 -1
  7. package/dist/task-manager.d.ts +23 -7
  8. package/dist/task-manager.js +31 -3
  9. package/dist/task-manager.js.map +1 -1
  10. package/dist/task-manager.mock.d.ts +3 -4
  11. package/dist/task-manager.mock.js +2 -3
  12. package/dist/task-manager.mock.js.map +1 -1
  13. package/dist/task-manager.test.js +58 -17
  14. package/dist/task-manager.test.js.map +1 -1
  15. package/dist/task-manager.types.d.ts +49 -37
  16. package/dist/user-registry.contract.d.ts +13 -0
  17. package/dist/user-registry.contract.js +130 -0
  18. package/dist/user-registry.contract.js.map +1 -0
  19. package/dist/user-registry.types.d.ts +51 -0
  20. package/dist/user-registry.types.js +2 -0
  21. package/dist/user-registry.types.js.map +1 -0
  22. package/package.json +17 -9
  23. package/src/index.ts +3 -3
  24. package/src/metrics.types.ts +2 -11
  25. package/src/provider-stats.test.ts +6 -3
  26. package/src/task-manager.mock.ts +4 -6
  27. package/src/task-manager.test.ts +83 -34
  28. package/src/task-manager.ts +44 -10
  29. package/src/task-manager.types.ts +56 -38
  30. package/src/user-registry.contract.ts +151 -0
  31. package/src/user-registry.types.ts +55 -0
  32. package/tsconfig.json +1 -0
  33. package/.turbo/turbo-build.log +0 -5
  34. package/.turbo/turbo-format.log +0 -18
  35. package/.turbo/turbo-install.log +0 -6
  36. package/.turbo/turbo-lint$colon$fix.log +0 -12
  37. package/.turbo/turbo-lint.log +0 -13
  38. package/.turbo/turbo-test.log +0 -15
  39. package/.turbo/turbo-typecheck.log +0 -5
  40. package/eslint.config.js +0 -8
  41. package/tsconfig.tsbuildinfo +0 -1
@@ -1,6 +1,7 @@
1
+ import { parseTaskId } from '@opentask/taskin-types';
1
2
  import { beforeEach, describe, expect, it, vi } from 'vitest';
2
- import { TaskManager } from './task-manager';
3
- import { createMockTask, createMockTaskProvider } from './task-manager.mock';
3
+ import { TaskManager } from './task-manager.js';
4
+ import { createMockTask, createMockTaskProvider } from './task-manager.mock.js';
4
5
  describe('TaskManager', () => {
5
6
  let taskManager;
6
7
  let mockTaskProvider;
@@ -14,26 +15,48 @@ describe('TaskManager', () => {
14
15
  describe('startTask', () => {
15
16
  it('should start a pending task', async () => {
16
17
  mockTaskProvider.findTask.mockResolvedValue(mockTask);
17
- const updatedTask = await taskManager.startTask('task-001');
18
- expect(mockTaskProvider.findTask).toHaveBeenCalledWith('task-001');
18
+ const updatedTask = await taskManager.startTask(parseTaskId('001'));
19
+ expect(mockTaskProvider.findTask).toHaveBeenCalledWith('001');
19
20
  expect(mockTaskProvider.updateTask).toHaveBeenCalledWith(expect.objectContaining({ status: 'in-progress' }));
20
21
  expect(updatedTask.status).toBe('in-progress');
21
22
  });
22
23
  it('should throw an error if task is not found', async () => {
23
24
  mockTaskProvider.findTask.mockResolvedValue(undefined);
24
- await expect(taskManager.startTask('not-found')).rejects.toThrow("Task with ID 'not-found' not found.");
25
+ await expect(taskManager.startTask(parseTaskId('999'))).rejects.toThrow("Task with ID '999' not found.");
25
26
  });
26
27
  it('should throw an error if task is already in progress', async () => {
27
28
  const inProgressTask = { ...mockTask, status: 'in-progress' };
28
29
  mockTaskProvider.findTask.mockResolvedValue(inProgressTask);
29
- await expect(taskManager.startTask('task-001')).rejects.toThrow("Task 'task-001' is already in progress.");
30
+ await expect(taskManager.startTask(parseTaskId('001'))).rejects.toThrow("Task '001' is already in progress.");
31
+ });
32
+ });
33
+ describe('pauseTask', () => {
34
+ it('should pause an in-progress task', async () => {
35
+ const inProgressTask = { ...mockTask, status: 'in-progress' };
36
+ mockTaskProvider.findTask.mockResolvedValue(inProgressTask);
37
+ const updatedTask = await taskManager.pauseTask(parseTaskId('001'));
38
+ expect(mockTaskProvider.updateTask).toHaveBeenCalledWith(expect.objectContaining({ status: 'paused' }));
39
+ expect(updatedTask.status).toBe('paused');
40
+ });
41
+ it('should throw an error if task is not found', async () => {
42
+ mockTaskProvider.findTask.mockResolvedValue(undefined);
43
+ await expect(taskManager.pauseTask(parseTaskId('999'))).rejects.toThrow("Task with ID '999' not found.");
44
+ });
45
+ it('should throw an error if task is not in-progress', async () => {
46
+ mockTaskProvider.findTask.mockResolvedValue({ ...mockTask, status: 'pending' });
47
+ await expect(taskManager.pauseTask(parseTaskId('001'))).rejects.toThrow("Task '001' must be in 'in-progress' status to be paused");
48
+ });
49
+ it('should let startTask resume a paused task', async () => {
50
+ mockTaskProvider.findTask.mockResolvedValue({ ...mockTask, status: 'paused' });
51
+ const updatedTask = await taskManager.startTask(parseTaskId('001'));
52
+ expect(updatedTask.status).toBe('in-progress');
30
53
  });
31
54
  });
32
55
  describe('finishTask', () => {
33
56
  it('should finish an in-progress task', async () => {
34
57
  const inProgressTask = { ...mockTask, status: 'in-progress' };
35
58
  mockTaskProvider.findTask.mockResolvedValue(inProgressTask);
36
- const updatedTask = await taskManager.finishTask('task-001');
59
+ const updatedTask = await taskManager.finishTask(parseTaskId('001'));
37
60
  expect(mockTaskProvider.updateTask).toHaveBeenCalledWith(expect.objectContaining({ status: 'done' }));
38
61
  expect(updatedTask.status).toBe('done');
39
62
  });
@@ -42,29 +65,46 @@ describe('TaskManager', () => {
42
65
  it('should change status to in-review for an in-progress task', async () => {
43
66
  const inProgressTask = { ...mockTask, status: 'in-progress' };
44
67
  mockTaskProvider.findTask.mockResolvedValue(inProgressTask);
45
- const updatedTask = await taskManager.reviewTask('task-001');
46
- expect(mockTaskProvider.findTask).toHaveBeenCalledWith('task-001');
68
+ const updatedTask = await taskManager.reviewTask(parseTaskId('001'));
69
+ expect(mockTaskProvider.findTask).toHaveBeenCalledWith('001');
47
70
  expect(mockTaskProvider.updateTask).toHaveBeenCalledWith(expect.objectContaining({ status: 'in-review' }));
48
71
  expect(updatedTask.status).toBe('in-review');
49
72
  });
50
73
  it('should throw an error if task is not found', async () => {
51
74
  mockTaskProvider.findTask.mockResolvedValue(undefined);
52
- await expect(taskManager.reviewTask('not-found')).rejects.toThrow("Task with ID 'not-found' not found.");
75
+ await expect(taskManager.reviewTask(parseTaskId('999'))).rejects.toThrow("Task with ID '999' not found.");
53
76
  });
54
77
  it('should throw an error if task is not in-progress', async () => {
55
78
  const pendingTask = { ...mockTask, status: 'pending' };
56
79
  mockTaskProvider.findTask.mockResolvedValue(pendingTask);
57
- await expect(taskManager.reviewTask('task-001')).rejects.toThrow("Task 'task-001' must be in 'in-progress' status to be reviewed");
80
+ await expect(taskManager.reviewTask(parseTaskId('001'))).rejects.toThrow("Task '001' must be in 'in-progress' status to be reviewed");
58
81
  });
59
82
  it('should throw an error if task is already done', async () => {
60
83
  const doneTask = { ...mockTask, status: 'done' };
61
84
  mockTaskProvider.findTask.mockResolvedValue(doneTask);
62
- await expect(taskManager.reviewTask('task-001')).rejects.toThrow("Task 'task-001' must be in 'in-progress' status to be reviewed");
85
+ await expect(taskManager.reviewTask(parseTaskId('001'))).rejects.toThrow("Task '001' must be in 'in-progress' status to be reviewed");
63
86
  });
64
87
  it('should throw an error if task is already in-review', async () => {
65
88
  const reviewTask = { ...mockTask, status: 'in-review' };
66
89
  mockTaskProvider.findTask.mockResolvedValue(reviewTask);
67
- await expect(taskManager.reviewTask('task-001')).rejects.toThrow("Task 'task-001' must be in 'in-progress' status to be reviewed");
90
+ await expect(taskManager.reviewTask(parseTaskId('001'))).rejects.toThrow("Task '001' must be in 'in-progress' status to be reviewed");
91
+ });
92
+ });
93
+ describe('provider-specific fields', () => {
94
+ it('should preserve provider fields through a transition', async () => {
95
+ const providerTask = {
96
+ ...createMockTask(),
97
+ filePath: '/tasks/task-001.md',
98
+ content: '# Task 001',
99
+ };
100
+ const provider = createMockTaskProvider();
101
+ provider.findTask.mockResolvedValue(providerTask);
102
+ const manager = new TaskManager(provider);
103
+ const updated = await manager.startTask(parseTaskId('001'));
104
+ expect(updated.filePath).toBe('/tasks/task-001.md');
105
+ expect(updated.content).toBe('# Task 001');
106
+ expect(updated.status).toBe('in-progress');
107
+ expect(provider.updateTask).toHaveBeenCalledWith(expect.objectContaining({ filePath: '/tasks/task-001.md' }));
68
108
  });
69
109
  });
70
110
  describe('createTask', () => {
@@ -72,7 +112,6 @@ describe('TaskManager', () => {
72
112
  const createOptions = { title: 'New Task', type: 'feat' };
73
113
  const createResult = {
74
114
  task: mockTask,
75
- taskId: '001',
76
115
  filePath: '/tasks/task-001.md',
77
116
  };
78
117
  mockTaskProvider.createTask.mockResolvedValue(createResult);
@@ -87,15 +126,17 @@ describe('TaskManager', () => {
87
126
  description: 'Fix something',
88
127
  assignee: 'john-doe',
89
128
  };
129
+ // Antes o assert batia no campo `taskId` do result, que dizia '002'
130
+ // enquanto o `task` dizia outro id. Com um campo so, o teste tem que
131
+ // devolver a task que ele afirma ter criado.
90
132
  const createResult = {
91
- task: mockTask,
92
- taskId: '002',
133
+ task: createMockTask({ id: parseTaskId('002') }),
93
134
  filePath: '/tasks/task-002.md',
94
135
  };
95
136
  mockTaskProvider.createTask.mockResolvedValue(createResult);
96
137
  const result = await taskManager.createTask(createOptions);
97
138
  expect(mockTaskProvider.createTask).toHaveBeenCalledWith(createOptions);
98
- expect(result.taskId).toBe('002');
139
+ expect(result.task.id).toBe('002');
99
140
  });
100
141
  });
101
142
  describe('lint', () => {
@@ -1 +1 @@
1
- {"version":3,"file":"task-manager.test.js","sourceRoot":"","sources":["../src/task-manager.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"task-manager.test.js","sourceRoot":"","sources":["../src/task-manager.test.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { Task, TaskType, User } from '@opentask/taskin-types';
1
+ import type { Task, TaskId, TaskType } from '@opentask/taskin-types';
2
2
  /**
3
3
  * Options for creating a new task
4
4
  * @public
@@ -14,16 +14,18 @@ export interface CreateTaskOptions {
14
14
  assignee?: string;
15
15
  }
16
16
  /**
17
- * Result of creating a new task
17
+ * Result of creating a new task.
18
+ *
19
+ * Providers are free to return a wider object (e.g. the file system provider
20
+ * adds `filePath`); returning extra fields is allowed because the result is
21
+ * only ever consumed through this contract.
22
+ *
23
+ * @typeParam TTask - The task shape produced by the provider
18
24
  * @public
19
25
  */
20
- export interface CreateTaskResult {
26
+ export interface CreateTaskResult<TTask extends Task = Task> {
21
27
  /** The created task */
22
- task: TaskFile;
23
- /** The generated task ID */
24
- taskId: string;
25
- /** The file path where the task was created */
26
- filePath: string;
28
+ task: TTask;
27
29
  }
28
30
  /**
29
31
  * Severity level for validation issues
@@ -62,69 +64,69 @@ export interface LintResult {
62
64
  /** Number of info messages */
63
65
  infoCount: number;
64
66
  }
65
- /**
66
- * A task with additional file system metadata.
67
- * Extends the base Task type with content and path information.
68
- * @public
69
- */
70
- export type TaskFile = Task & {
71
- /** The raw markdown content of the task file */
72
- content: string;
73
- /** Absolute or relative path to the task file */
74
- filePath: string;
75
- /** The type of work this task represents */
76
- type: TaskType;
77
- /** Optional user assigned to this task */
78
- assignee?: User;
79
- };
80
67
  /**
81
68
  * Interface for task storage providers.
82
69
  * Implementations handle reading and writing tasks from different sources
83
- * (e.g., file system, database, API).
70
+ * (e.g., file system, GitHub issues, Redmine).
71
+ *
72
+ * The task shape is a type parameter so that a provider can enrich `Task` with
73
+ * whatever its backing store requires — the file system provider carries
74
+ * `content`/`filePath`, a Redmine provider would carry its own fields — without
75
+ * that shape leaking into this package. Consumers that do not care about the
76
+ * extra fields can simply use the default and work with plain `Task`.
77
+ *
78
+ * @typeParam TTask - The task shape this provider reads and writes
84
79
  * @public
85
80
  */
86
- export interface ITaskProvider {
81
+ export interface ITaskProvider<TTask extends Task = Task> {
87
82
  /**
88
83
  * Initialize the provider, performing any necessary setup or loading.
89
84
  * This may involve reading existing tasks, setting up connections, etc.
90
85
  */
91
- initialize(): Promise<void>;
86
+ initialize: () => Promise<void>;
92
87
  /**
93
88
  * Find a specific task by its ID.
94
89
  * @param taskId - The unique identifier of the task
95
90
  * @returns The task if found, undefined otherwise
96
91
  */
97
- findTask(taskId: string): Promise<TaskFile | undefined>;
92
+ findTask: (taskId: TaskId) => Promise<TTask | undefined>;
98
93
  /**
99
94
  * Retrieve all tasks from the provider.
100
95
  * @returns Array of all tasks
101
96
  */
102
- getAllTasks(): Promise<TaskFile[]>;
97
+ getAllTasks: () => Promise<TTask[]>;
103
98
  /**
104
99
  * Update an existing task.
105
100
  * @param task - The task with updated information
106
101
  */
107
- updateTask(task: TaskFile): Promise<void>;
102
+ updateTask: (task: TTask) => Promise<void>;
108
103
  /**
109
104
  * Create a new task.
110
105
  * @param options - Options for creating the task
111
106
  * @returns The created task information
112
107
  */
113
- createTask(options: CreateTaskOptions): Promise<CreateTaskResult>;
108
+ createTask: (options: CreateTaskOptions) => Promise<CreateTaskResult<TTask>>;
114
109
  /**
115
110
  * Validate all tasks managed by this provider.
116
111
  * Each provider knows its own format and validation rules.
117
112
  * @param fix - If true, attempt to automatically fix validation issues
118
113
  * @returns The lint result with any validation issues found
119
114
  */
120
- lint(fix?: boolean): Promise<LintResult>;
115
+ lint: (fix?: boolean) => Promise<LintResult>;
121
116
  }
122
117
  /**
123
118
  * Interface for task management operations.
124
119
  * Provides high-level methods for managing task workflow and state transitions.
120
+ *
121
+ * Mirrors the provider's task shape: a manager built on top of the file system
122
+ * provider hands back the provider's richer task, while a manager built on any
123
+ * other provider hands back that provider's shape. This package never needs to
124
+ * know which one it is.
125
+ *
126
+ * @typeParam TTask - The task shape produced by the underlying provider
125
127
  * @public
126
128
  */
127
- export interface ITaskManager {
129
+ export interface ITaskManager<TTask extends Task = Task> {
128
130
  /**
129
131
  * Mark a task as finished.
130
132
  * Transitions the task to 'done' status.
@@ -132,7 +134,7 @@ export interface ITaskManager {
132
134
  * @returns The updated task
133
135
  * @throws Error if task is not found
134
136
  */
135
- finishTask(taskId: string): Promise<TaskFile>;
137
+ finishTask: (taskId: TaskId) => Promise<TTask>;
136
138
  /**
137
139
  * Mark a task as ready for review.
138
140
  * Transitions the task from 'in-progress' to 'in-review' status.
@@ -140,26 +142,36 @@ export interface ITaskManager {
140
142
  * @returns The updated task
141
143
  * @throws Error if task is not found or not in 'in-progress' status
142
144
  */
143
- reviewTask(taskId: string): Promise<TaskFile>;
145
+ reviewTask: (taskId: TaskId) => Promise<TTask>;
144
146
  /**
145
147
  * Start working on a task.
146
148
  * Transitions the task to 'in-progress' status.
149
+ * Also used to resume a paused task.
147
150
  * @param taskId - The unique identifier of the task
148
151
  * @returns The updated task
149
152
  * @throws Error if task is not found, already in progress, or already done
150
153
  */
151
- startTask(taskId: string): Promise<TaskFile>;
154
+ startTask: (taskId: TaskId) => Promise<TTask>;
155
+ /**
156
+ * Pause work on a task.
157
+ * Transitions the task from 'in-progress' to 'paused' status.
158
+ * Resume with {@link ITaskManager.startTask}.
159
+ * @param taskId - The unique identifier of the task
160
+ * @returns The updated task
161
+ * @throws Error if task is not found or not in 'in-progress' status
162
+ */
163
+ pauseTask: (taskId: TaskId) => Promise<TTask>;
152
164
  /**
153
165
  * Create a new task.
154
166
  * @param options - Options for creating the task
155
167
  * @returns The created task information
156
168
  */
157
- createTask(options: CreateTaskOptions): Promise<CreateTaskResult>;
169
+ createTask: (options: CreateTaskOptions) => Promise<CreateTaskResult<TTask>>;
158
170
  /**
159
171
  * Validate all tasks in the system.
160
172
  * Delegates to the underlying provider's lint implementation.
161
173
  * @param fix - If true, attempt to automatically fix validation issues
162
174
  * @returns The lint result with any validation issues found
163
175
  */
164
- lint(fix?: boolean): Promise<LintResult>;
176
+ lint: (fix?: boolean) => Promise<LintResult>;
165
177
  }
@@ -0,0 +1,13 @@
1
+ import type { IUserRegistry } from './user-registry.types.js';
2
+ /**
3
+ * Contract suite every {@link IUserRegistry} implementation must pass.
4
+ *
5
+ * Lives in the agnostic package on purpose: a provider-specific registry (file
6
+ * backed, GitHub, Redmine) proves itself against the same behaviour, and none of
7
+ * them has to depend on another provider's package to do it. Exported through
8
+ * the `./testing` subpath so `vitest` never enters the runtime import graph.
9
+ *
10
+ * @param createSubject - Builds a fresh, empty registry for each test
11
+ * @public
12
+ */
13
+ export declare function runUserRegistryContractTests(createSubject: () => Promise<IUserRegistry>): void;
@@ -0,0 +1,130 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ /**
3
+ * Contract suite every {@link IUserRegistry} implementation must pass.
4
+ *
5
+ * Lives in the agnostic package on purpose: a provider-specific registry (file
6
+ * backed, GitHub, Redmine) proves itself against the same behaviour, and none of
7
+ * them has to depend on another provider's package to do it. Exported through
8
+ * the `./testing` subpath so `vitest` never enters the runtime import graph.
9
+ *
10
+ * @param createSubject - Builds a fresh, empty registry for each test
11
+ * @public
12
+ */
13
+ export function runUserRegistryContractTests(createSubject) {
14
+ describe('IUserRegistry contract', () => {
15
+ describe('saveUser / getUser', () => {
16
+ it('should store and retrieve a user by ID', async () => {
17
+ const registry = await createSubject();
18
+ const user = { id: 'ana', name: 'Ana', email: 'ana@example.com' };
19
+ await registry.saveUser(user);
20
+ expect(registry.getUser('ana')).toEqual(user);
21
+ });
22
+ it('should return undefined for unknown user', async () => {
23
+ const registry = await createSubject();
24
+ expect(registry.getUser('unknown')).toBeUndefined();
25
+ });
26
+ });
27
+ describe('resolveUser', () => {
28
+ it('should return user by ID with avatar', async () => {
29
+ const registry = await createSubject();
30
+ await registry.saveUser({
31
+ id: 'joao.silva',
32
+ name: 'João Silva',
33
+ email: 'joao@example.com',
34
+ });
35
+ const user = registry.resolveUser('joao.silva');
36
+ expect(user).toBeDefined();
37
+ expect(user.id).toBe('joao.silva');
38
+ expect(user.avatar).toMatch(/^https:\/\/www\.gravatar\.com\/avatar\/[a-f0-9]{32}\?d=mp$/);
39
+ });
40
+ it('should return user by name (case-insensitive)', async () => {
41
+ const registry = await createSubject();
42
+ await registry.saveUser({
43
+ id: 'maria',
44
+ name: 'Maria Souza',
45
+ email: 'maria@example.com',
46
+ });
47
+ const user = registry.resolveUser('Maria Souza');
48
+ expect(user).toBeDefined();
49
+ expect(user.id).toBe('maria');
50
+ expect(user.avatar).toMatch(/^https:\/\/www\.gravatar\.com\/avatar\/[a-f0-9]{32}\?d=mp$/);
51
+ });
52
+ it('should return undefined for unknown user', async () => {
53
+ const registry = await createSubject();
54
+ const user = registry.resolveUser('unknown');
55
+ expect(user).toBeUndefined();
56
+ });
57
+ });
58
+ describe('createTemporaryUser', () => {
59
+ it('should create user with Gravatar URL', async () => {
60
+ const registry = await createSubject();
61
+ const user = registry.createTemporaryUser('Carlos');
62
+ expect(user.id).toBe('carlos');
63
+ expect(user.name).toBe('Carlos');
64
+ expect(user.email).toBe('carlos@example.com');
65
+ expect(user.avatar).toMatch(/^https:\/\/www\.gravatar\.com\/avatar\/[a-f0-9]{32}\?d=mp$/);
66
+ });
67
+ it('should create different Gravatar URLs for different inputs', async () => {
68
+ const registry = await createSubject();
69
+ const user1 = registry.createTemporaryUser('Alice');
70
+ const user2 = registry.createTemporaryUser('Bob');
71
+ expect(user1.avatar).not.toBe(user2.avatar);
72
+ });
73
+ });
74
+ describe('ensureCurrentUser', () => {
75
+ it('should create and return a user when registry is empty', async () => {
76
+ const registry = await createSubject();
77
+ const user = await registry.ensureCurrentUser({
78
+ name: 'Test User',
79
+ email: 'test@test.com',
80
+ });
81
+ expect(user.id).toBe('test-user');
82
+ expect(user.name).toBe('Test User');
83
+ expect(user.email).toBe('test@test.com');
84
+ });
85
+ it('should return existing user when email matches', async () => {
86
+ const registry = await createSubject();
87
+ await registry.saveUser({
88
+ id: 'maria',
89
+ name: 'Maria Souza',
90
+ email: 'maria@example.com',
91
+ });
92
+ const user = await registry.ensureCurrentUser({
93
+ name: 'Maria Souza',
94
+ email: 'maria@example.com',
95
+ });
96
+ expect(user.id).toBe('maria');
97
+ expect(registry.getAllUsers()).toHaveLength(1);
98
+ });
99
+ it('should create new user when email does not match any existing', async () => {
100
+ const registry = await createSubject();
101
+ await registry.saveUser({
102
+ id: 'joao',
103
+ name: 'João',
104
+ email: 'joao@example.com',
105
+ });
106
+ const user = await registry.ensureCurrentUser({
107
+ name: 'Maria',
108
+ email: 'maria@example.com',
109
+ });
110
+ expect(user.id).toBe('maria');
111
+ expect(registry.getAllUsers()).toHaveLength(2);
112
+ });
113
+ });
114
+ describe('getAllUsers', () => {
115
+ it('should return all saved users', async () => {
116
+ const registry = await createSubject();
117
+ await registry.saveUser({ id: 'a', name: 'A', email: 'a@a.com' });
118
+ await registry.saveUser({ id: 'b', name: 'B', email: 'b@b.com' });
119
+ const all = registry.getAllUsers();
120
+ expect(all).toHaveLength(2);
121
+ expect(all.map((u) => u.id)).toEqual(expect.arrayContaining(['a', 'b']));
122
+ });
123
+ it('should return empty array when no users', async () => {
124
+ const registry = await createSubject();
125
+ expect(registry.getAllUsers()).toEqual([]);
126
+ });
127
+ });
128
+ });
129
+ }
130
+ //# sourceMappingURL=user-registry.contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-registry.contract.js","sourceRoot":"","sources":["../src/user-registry.contract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import type { User } from '@opentask/taskin-types';
2
+ /**
3
+ * Interface for user directories.
4
+ *
5
+ * Resolving an assignee to a {@link User} is something every provider needs, and
6
+ * each one answers it from a different place: the file system provider keeps a
7
+ * JSON registry in `.taskin/`, a GitHub provider reads the issue's `assignees`
8
+ * from the API, a Redmine provider queries its own user directory. So this port
9
+ * lives here, next to {@link ITaskProvider}, and not inside any one provider —
10
+ * declaring it in the file system package meant a remote provider had to import
11
+ * from the file system provider just to implement it, the same boundary leak
12
+ * that `TaskFile` had before task-031.
13
+ *
14
+ * A provider receives its registry injected; it never builds one. Implementations
15
+ * are expected to pass the contract suite exported from
16
+ * `@opentask/taskin-task-manager/testing`.
17
+ *
18
+ * @public
19
+ */
20
+ export interface IUserRegistry {
21
+ /** Load the directory into memory, if the implementation needs a warm-up. */
22
+ load(): Promise<void>;
23
+ /**
24
+ * Look up a user by their exact id.
25
+ * @returns The user, or `undefined` when the id is unknown
26
+ */
27
+ getUser(userId: string): User | undefined;
28
+ /**
29
+ * Look up a user by id or display name.
30
+ * @returns The user, or `undefined` when nothing matches
31
+ */
32
+ resolveUser(nameOrId: string): User | undefined;
33
+ /**
34
+ * Ensure the person running the command exists in the directory, creating the
35
+ * entry when it does not.
36
+ * @param gitConfig - Identity to fall back on when the directory has no better source
37
+ */
38
+ ensureCurrentUser(gitConfig?: {
39
+ name: string;
40
+ email: string;
41
+ }): Promise<User>;
42
+ /**
43
+ * Build an in-memory user for a name that is not in the directory, so an
44
+ * unknown assignee degrades instead of failing the whole read.
45
+ */
46
+ createTemporaryUser(nameOrId: string): User;
47
+ /** Every user the directory knows about. */
48
+ getAllUsers(): User[];
49
+ /** Persist a user in the directory. */
50
+ saveUser(user: User): Promise<void>;
51
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=user-registry.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-registry.types.js","sourceRoot":"","sources":["../src/user-registry.types.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opentask/taskin-task-manager",
3
- "version": "2.0.1",
3
+ "version": "3.0.0",
4
4
  "description": "Task lifecycle management for Taskin",
5
5
  "type": "module",
6
6
  "motivation": "To manage the lifecycle of tasks, including creation, status updates, and retrieval.",
@@ -28,23 +28,31 @@
28
28
  "exports": {
29
29
  ".": {
30
30
  "types": "./dist/index.d.ts",
31
- "import": "./dist/index.js"
31
+ "import": "./dist/index.js",
32
+ "require": "./dist/index.js",
33
+ "default": "./dist/index.js"
34
+ },
35
+ "./testing": {
36
+ "types": "./dist/user-registry.contract.d.ts",
37
+ "import": "./dist/user-registry.contract.js",
38
+ "require": "./dist/user-registry.contract.js",
39
+ "default": "./dist/user-registry.contract.js"
32
40
  }
33
41
  },
34
42
  "dependencies": {
35
- "@opentask/taskin-types": "1.1.1"
43
+ "@opentask/taskin-types": "2.0.0"
36
44
  },
37
45
  "devDependencies": {
38
- "typescript": "^5.9.3"
46
+ "typescript": "^6.0.0"
39
47
  },
40
48
  "scripts": {
41
- "build": "tsc",
49
+ "build": "tsc && node ../../scripts/fix-esm-extensions.mjs dist",
42
50
  "clean": "rm -rf dist coverage .turbo",
43
51
  "dev": "tsc --watch",
44
- "format": "prettier --write .",
45
- "format:check": "prettier --check .",
46
- "lint": "eslint .",
47
- "lint:fix": "eslint . --fix",
52
+ "format": "biome check --write .",
53
+ "format:check": "biome check .",
54
+ "lint": "biome check .",
55
+ "lint:fix": "biome check --write .",
48
56
  "test": "vitest run",
49
57
  "test:coverage": "vitest run --coverage",
50
58
  "typecheck": "tsc --noEmit"
package/src/index.ts CHANGED
@@ -1,6 +1,6 @@
1
+ // Re-export commonly used types from @opentask/taskin-types for convenience
2
+ export type { Task, TaskStatus, TaskType, User } from '@opentask/taskin-types';
1
3
  export * from './metrics.types';
2
4
  export * from './task-manager';
3
5
  export * from './task-manager.types';
4
-
5
- // Re-export commonly used types from @opentask/taskin-types for convenience
6
- export type { Task, TaskStatus, TaskType, User } from '@opentask/taskin-types';
6
+ export * from './user-registry.types';