gitx.do 0.0.1 → 0.0.3

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 (237) hide show
  1. package/dist/cli/commands/blame.d.ts +259 -0
  2. package/dist/cli/commands/blame.d.ts.map +1 -0
  3. package/dist/cli/commands/blame.js +609 -0
  4. package/dist/cli/commands/blame.js.map +1 -0
  5. package/dist/cli/commands/branch.d.ts +249 -0
  6. package/dist/cli/commands/branch.d.ts.map +1 -0
  7. package/dist/cli/commands/branch.js +693 -0
  8. package/dist/cli/commands/branch.js.map +1 -0
  9. package/dist/cli/commands/commit.d.ts +182 -0
  10. package/dist/cli/commands/commit.d.ts.map +1 -0
  11. package/dist/cli/commands/commit.js +437 -0
  12. package/dist/cli/commands/commit.js.map +1 -0
  13. package/dist/cli/commands/diff.d.ts +464 -0
  14. package/dist/cli/commands/diff.d.ts.map +1 -0
  15. package/dist/cli/commands/diff.js +958 -0
  16. package/dist/cli/commands/diff.js.map +1 -0
  17. package/dist/cli/commands/log.d.ts +239 -0
  18. package/dist/cli/commands/log.d.ts.map +1 -0
  19. package/dist/cli/commands/log.js +535 -0
  20. package/dist/cli/commands/log.js.map +1 -0
  21. package/dist/cli/commands/review.d.ts +457 -0
  22. package/dist/cli/commands/review.d.ts.map +1 -0
  23. package/dist/cli/commands/review.js +533 -0
  24. package/dist/cli/commands/review.js.map +1 -0
  25. package/dist/cli/commands/status.d.ts +269 -0
  26. package/dist/cli/commands/status.d.ts.map +1 -0
  27. package/dist/cli/commands/status.js +493 -0
  28. package/dist/cli/commands/status.js.map +1 -0
  29. package/dist/cli/commands/web.d.ts +199 -0
  30. package/dist/cli/commands/web.d.ts.map +1 -0
  31. package/dist/cli/commands/web.js +696 -0
  32. package/dist/cli/commands/web.js.map +1 -0
  33. package/dist/cli/fs-adapter.d.ts +656 -0
  34. package/dist/cli/fs-adapter.d.ts.map +1 -0
  35. package/dist/cli/fs-adapter.js +1179 -0
  36. package/dist/cli/fs-adapter.js.map +1 -0
  37. package/dist/cli/index.d.ts +387 -0
  38. package/dist/cli/index.d.ts.map +1 -0
  39. package/dist/cli/index.js +523 -0
  40. package/dist/cli/index.js.map +1 -0
  41. package/dist/cli/ui/components/DiffView.d.ts +7 -0
  42. package/dist/cli/ui/components/DiffView.d.ts.map +1 -0
  43. package/dist/cli/ui/components/DiffView.js +11 -0
  44. package/dist/cli/ui/components/DiffView.js.map +1 -0
  45. package/dist/cli/ui/components/ErrorDisplay.d.ts +6 -0
  46. package/dist/cli/ui/components/ErrorDisplay.d.ts.map +1 -0
  47. package/dist/cli/ui/components/ErrorDisplay.js +11 -0
  48. package/dist/cli/ui/components/ErrorDisplay.js.map +1 -0
  49. package/dist/cli/ui/components/FuzzySearch.d.ts +9 -0
  50. package/dist/cli/ui/components/FuzzySearch.d.ts.map +1 -0
  51. package/dist/cli/ui/components/FuzzySearch.js +12 -0
  52. package/dist/cli/ui/components/FuzzySearch.js.map +1 -0
  53. package/dist/cli/ui/components/LoadingSpinner.d.ts +6 -0
  54. package/dist/cli/ui/components/LoadingSpinner.d.ts.map +1 -0
  55. package/dist/cli/ui/components/LoadingSpinner.js +10 -0
  56. package/dist/cli/ui/components/LoadingSpinner.js.map +1 -0
  57. package/dist/cli/ui/components/NavigationList.d.ts +9 -0
  58. package/dist/cli/ui/components/NavigationList.d.ts.map +1 -0
  59. package/dist/cli/ui/components/NavigationList.js +11 -0
  60. package/dist/cli/ui/components/NavigationList.js.map +1 -0
  61. package/dist/cli/ui/components/ScrollableContent.d.ts +8 -0
  62. package/dist/cli/ui/components/ScrollableContent.d.ts.map +1 -0
  63. package/dist/cli/ui/components/ScrollableContent.js +11 -0
  64. package/dist/cli/ui/components/ScrollableContent.js.map +1 -0
  65. package/dist/cli/ui/components/index.d.ts +7 -0
  66. package/dist/cli/ui/components/index.d.ts.map +1 -0
  67. package/dist/cli/ui/components/index.js +9 -0
  68. package/dist/cli/ui/components/index.js.map +1 -0
  69. package/dist/cli/ui/terminal-ui.d.ts +52 -0
  70. package/dist/cli/ui/terminal-ui.d.ts.map +1 -0
  71. package/dist/cli/ui/terminal-ui.js +121 -0
  72. package/dist/cli/ui/terminal-ui.js.map +1 -0
  73. package/dist/durable-object/object-store.d.ts +401 -23
  74. package/dist/durable-object/object-store.d.ts.map +1 -1
  75. package/dist/durable-object/object-store.js +414 -25
  76. package/dist/durable-object/object-store.js.map +1 -1
  77. package/dist/durable-object/schema.d.ts +188 -0
  78. package/dist/durable-object/schema.d.ts.map +1 -1
  79. package/dist/durable-object/schema.js +160 -0
  80. package/dist/durable-object/schema.js.map +1 -1
  81. package/dist/durable-object/wal.d.ts +336 -31
  82. package/dist/durable-object/wal.d.ts.map +1 -1
  83. package/dist/durable-object/wal.js +272 -27
  84. package/dist/durable-object/wal.js.map +1 -1
  85. package/dist/index.d.ts +379 -3
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +379 -7
  88. package/dist/index.js.map +1 -1
  89. package/dist/mcp/adapter.d.ts +579 -38
  90. package/dist/mcp/adapter.d.ts.map +1 -1
  91. package/dist/mcp/adapter.js +426 -33
  92. package/dist/mcp/adapter.js.map +1 -1
  93. package/dist/mcp/sandbox.d.ts +532 -29
  94. package/dist/mcp/sandbox.d.ts.map +1 -1
  95. package/dist/mcp/sandbox.js +389 -22
  96. package/dist/mcp/sandbox.js.map +1 -1
  97. package/dist/mcp/sdk-adapter.d.ts +478 -56
  98. package/dist/mcp/sdk-adapter.d.ts.map +1 -1
  99. package/dist/mcp/sdk-adapter.js +346 -44
  100. package/dist/mcp/sdk-adapter.js.map +1 -1
  101. package/dist/mcp/tools.d.ts +445 -30
  102. package/dist/mcp/tools.d.ts.map +1 -1
  103. package/dist/mcp/tools.js +363 -33
  104. package/dist/mcp/tools.js.map +1 -1
  105. package/dist/ops/blame.d.ts +424 -21
  106. package/dist/ops/blame.d.ts.map +1 -1
  107. package/dist/ops/blame.js +303 -20
  108. package/dist/ops/blame.js.map +1 -1
  109. package/dist/ops/branch.d.ts +583 -32
  110. package/dist/ops/branch.d.ts.map +1 -1
  111. package/dist/ops/branch.js +365 -23
  112. package/dist/ops/branch.js.map +1 -1
  113. package/dist/ops/commit-traversal.d.ts +164 -24
  114. package/dist/ops/commit-traversal.d.ts.map +1 -1
  115. package/dist/ops/commit-traversal.js +68 -2
  116. package/dist/ops/commit-traversal.js.map +1 -1
  117. package/dist/ops/commit.d.ts +387 -53
  118. package/dist/ops/commit.d.ts.map +1 -1
  119. package/dist/ops/commit.js +249 -29
  120. package/dist/ops/commit.js.map +1 -1
  121. package/dist/ops/merge-base.d.ts +195 -21
  122. package/dist/ops/merge-base.d.ts.map +1 -1
  123. package/dist/ops/merge-base.js +122 -12
  124. package/dist/ops/merge-base.js.map +1 -1
  125. package/dist/ops/merge.d.ts +600 -130
  126. package/dist/ops/merge.d.ts.map +1 -1
  127. package/dist/ops/merge.js +408 -60
  128. package/dist/ops/merge.js.map +1 -1
  129. package/dist/ops/tag.d.ts +67 -2
  130. package/dist/ops/tag.d.ts.map +1 -1
  131. package/dist/ops/tag.js +42 -1
  132. package/dist/ops/tag.js.map +1 -1
  133. package/dist/ops/tree-builder.d.ts +102 -6
  134. package/dist/ops/tree-builder.d.ts.map +1 -1
  135. package/dist/ops/tree-builder.js +30 -5
  136. package/dist/ops/tree-builder.js.map +1 -1
  137. package/dist/ops/tree-diff.d.ts +50 -2
  138. package/dist/ops/tree-diff.d.ts.map +1 -1
  139. package/dist/ops/tree-diff.js +50 -2
  140. package/dist/ops/tree-diff.js.map +1 -1
  141. package/dist/pack/delta.d.ts +211 -39
  142. package/dist/pack/delta.d.ts.map +1 -1
  143. package/dist/pack/delta.js +232 -46
  144. package/dist/pack/delta.js.map +1 -1
  145. package/dist/pack/format.d.ts +390 -28
  146. package/dist/pack/format.d.ts.map +1 -1
  147. package/dist/pack/format.js +344 -33
  148. package/dist/pack/format.js.map +1 -1
  149. package/dist/pack/full-generation.d.ts +313 -28
  150. package/dist/pack/full-generation.d.ts.map +1 -1
  151. package/dist/pack/full-generation.js +238 -19
  152. package/dist/pack/full-generation.js.map +1 -1
  153. package/dist/pack/generation.d.ts +346 -23
  154. package/dist/pack/generation.d.ts.map +1 -1
  155. package/dist/pack/generation.js +269 -21
  156. package/dist/pack/generation.js.map +1 -1
  157. package/dist/pack/index.d.ts +407 -86
  158. package/dist/pack/index.d.ts.map +1 -1
  159. package/dist/pack/index.js +351 -70
  160. package/dist/pack/index.js.map +1 -1
  161. package/dist/refs/branch.d.ts +517 -71
  162. package/dist/refs/branch.d.ts.map +1 -1
  163. package/dist/refs/branch.js +410 -26
  164. package/dist/refs/branch.js.map +1 -1
  165. package/dist/refs/storage.d.ts +610 -57
  166. package/dist/refs/storage.d.ts.map +1 -1
  167. package/dist/refs/storage.js +481 -29
  168. package/dist/refs/storage.js.map +1 -1
  169. package/dist/refs/tag.d.ts +677 -67
  170. package/dist/refs/tag.d.ts.map +1 -1
  171. package/dist/refs/tag.js +497 -30
  172. package/dist/refs/tag.js.map +1 -1
  173. package/dist/storage/lru-cache.d.ts +556 -53
  174. package/dist/storage/lru-cache.d.ts.map +1 -1
  175. package/dist/storage/lru-cache.js +439 -36
  176. package/dist/storage/lru-cache.js.map +1 -1
  177. package/dist/storage/object-index.d.ts +483 -38
  178. package/dist/storage/object-index.d.ts.map +1 -1
  179. package/dist/storage/object-index.js +388 -22
  180. package/dist/storage/object-index.js.map +1 -1
  181. package/dist/storage/r2-pack.d.ts +957 -94
  182. package/dist/storage/r2-pack.d.ts.map +1 -1
  183. package/dist/storage/r2-pack.js +756 -48
  184. package/dist/storage/r2-pack.js.map +1 -1
  185. package/dist/tiered/cdc-pipeline.d.ts +1610 -38
  186. package/dist/tiered/cdc-pipeline.d.ts.map +1 -1
  187. package/dist/tiered/cdc-pipeline.js +1131 -22
  188. package/dist/tiered/cdc-pipeline.js.map +1 -1
  189. package/dist/tiered/migration.d.ts +903 -41
  190. package/dist/tiered/migration.d.ts.map +1 -1
  191. package/dist/tiered/migration.js +646 -24
  192. package/dist/tiered/migration.js.map +1 -1
  193. package/dist/tiered/parquet-writer.d.ts +944 -47
  194. package/dist/tiered/parquet-writer.d.ts.map +1 -1
  195. package/dist/tiered/parquet-writer.js +667 -39
  196. package/dist/tiered/parquet-writer.js.map +1 -1
  197. package/dist/tiered/read-path.d.ts +728 -34
  198. package/dist/tiered/read-path.d.ts.map +1 -1
  199. package/dist/tiered/read-path.js +310 -27
  200. package/dist/tiered/read-path.js.map +1 -1
  201. package/dist/types/objects.d.ts +457 -0
  202. package/dist/types/objects.d.ts.map +1 -1
  203. package/dist/types/objects.js +305 -4
  204. package/dist/types/objects.js.map +1 -1
  205. package/dist/types/storage.d.ts +407 -35
  206. package/dist/types/storage.d.ts.map +1 -1
  207. package/dist/types/storage.js +27 -3
  208. package/dist/types/storage.js.map +1 -1
  209. package/dist/utils/hash.d.ts +133 -12
  210. package/dist/utils/hash.d.ts.map +1 -1
  211. package/dist/utils/hash.js +133 -12
  212. package/dist/utils/hash.js.map +1 -1
  213. package/dist/utils/sha1.d.ts +102 -9
  214. package/dist/utils/sha1.d.ts.map +1 -1
  215. package/dist/utils/sha1.js +114 -11
  216. package/dist/utils/sha1.js.map +1 -1
  217. package/dist/wire/capabilities.d.ts +896 -88
  218. package/dist/wire/capabilities.d.ts.map +1 -1
  219. package/dist/wire/capabilities.js +566 -62
  220. package/dist/wire/capabilities.js.map +1 -1
  221. package/dist/wire/pkt-line.d.ts +293 -15
  222. package/dist/wire/pkt-line.d.ts.map +1 -1
  223. package/dist/wire/pkt-line.js +251 -15
  224. package/dist/wire/pkt-line.js.map +1 -1
  225. package/dist/wire/receive-pack.d.ts +814 -64
  226. package/dist/wire/receive-pack.d.ts.map +1 -1
  227. package/dist/wire/receive-pack.js +542 -41
  228. package/dist/wire/receive-pack.js.map +1 -1
  229. package/dist/wire/smart-http.d.ts +575 -97
  230. package/dist/wire/smart-http.d.ts.map +1 -1
  231. package/dist/wire/smart-http.js +337 -46
  232. package/dist/wire/smart-http.js.map +1 -1
  233. package/dist/wire/upload-pack.d.ts +492 -98
  234. package/dist/wire/upload-pack.d.ts.map +1 -1
  235. package/dist/wire/upload-pack.js +347 -59
  236. package/dist/wire/upload-pack.js.map +1 -1
  237. package/package.json +10 -2
@@ -1,175 +1,615 @@
1
1
  /**
2
- * Git Tag Operations
2
+ * @fileoverview Git Tag Operations
3
3
  *
4
- * Handles creation, deletion, and management of Git tags.
5
- * Supports both lightweight tags (refs pointing to commits)
6
- * and annotated tags (tag objects with metadata).
4
+ * This module provides comprehensive tag management functionality including
5
+ * creation (lightweight and annotated), deletion, listing, and verification.
6
+ *
7
+ * **Tag Types in Git**:
8
+ * - **Lightweight tags**: Simple refs under refs/tags/ pointing to commits
9
+ * - **Annotated tags**: Refs pointing to tag objects containing metadata
10
+ * (tagger, date, message, and optional GPG signature)
11
+ *
12
+ * Annotated tags are recommended for releases as they include metadata
13
+ * and can be cryptographically signed.
14
+ *
15
+ * @module refs/tag
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * import { TagManager, createTag, listTags } from './refs/tag'
20
+ *
21
+ * // Create manager
22
+ * const manager = new TagManager(refStorage, objectStorage, gpgSigner)
23
+ *
24
+ * // Create annotated tag
25
+ * const tag = await manager.createTag('v1.0.0', commitSha, {
26
+ * annotated: true,
27
+ * message: 'Release 1.0.0',
28
+ * tagger: { name: 'Alice', email: 'alice@example.com', timestamp: Date.now()/1000, timezone: '+0000' }
29
+ * })
30
+ *
31
+ * // List version tags
32
+ * const versions = await listTags(manager, { pattern: 'v*' })
33
+ * ```
7
34
  */
8
35
  import { Author, TagObject, ObjectType } from '../types/objects';
9
36
  import { RefStorage, RefErrorCode } from './storage';
10
37
  /**
11
- * Tag type discriminator
38
+ * Tag type discriminator.
39
+ *
40
+ * @description
41
+ * - `lightweight`: Simple ref pointing directly to a commit
42
+ * - `annotated`: Ref pointing to a tag object containing metadata
12
43
  */
13
44
  export type TagType = 'lightweight' | 'annotated';
14
45
  /**
15
- * Represents a Git tag (either lightweight or annotated)
46
+ * Represents a Git tag (either lightweight or annotated).
47
+ *
48
+ * @description
49
+ * Unified interface for both lightweight and annotated tags.
50
+ * For annotated tags, includes additional metadata from the tag object.
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * // Lightweight tag
55
+ * const light: Tag = {
56
+ * name: 'v0.1.0',
57
+ * type: 'lightweight',
58
+ * sha: 'commitsha...'
59
+ * }
60
+ *
61
+ * // Annotated tag
62
+ * const annotated: Tag = {
63
+ * name: 'v1.0.0',
64
+ * type: 'annotated',
65
+ * sha: 'tagobjectsha...',
66
+ * targetSha: 'commitsha...',
67
+ * targetType: 'commit',
68
+ * tagger: { name: 'Alice', email: 'alice@example.com', timestamp: 1704067200, timezone: '+0000' },
69
+ * message: 'Release 1.0.0'
70
+ * }
71
+ * ```
16
72
  */
17
73
  export interface Tag {
18
- /** Tag name (e.g., 'v1.0.0') */
74
+ /** Tag name (e.g., 'v1.0.0') without refs/tags/ prefix */
19
75
  name: string;
20
- /** Tag type */
76
+ /** Tag type: 'lightweight' or 'annotated' */
21
77
  type: TagType;
22
- /** Target SHA - for lightweight: commit SHA, for annotated: tag object SHA */
78
+ /**
79
+ * SHA this ref points to.
80
+ * For lightweight tags: commit SHA
81
+ * For annotated tags: tag object SHA
82
+ */
23
83
  sha: string;
24
- /** For annotated tags: the commit/object the tag points to */
84
+ /**
85
+ * For annotated tags: the commit/object the tag points to.
86
+ * Undefined for lightweight tags.
87
+ */
25
88
  targetSha?: string;
26
- /** For annotated tags: the type of object being tagged */
89
+ /**
90
+ * For annotated tags: the type of object being tagged.
91
+ * Usually 'commit', but could be 'blob', 'tree', or even 'tag'.
92
+ */
27
93
  targetType?: ObjectType;
28
- /** For annotated tags: the tagger information */
94
+ /**
95
+ * For annotated tags: the tagger information.
96
+ * Contains name, email, timestamp, and timezone.
97
+ */
29
98
  tagger?: Author;
30
- /** For annotated tags: the tag message */
99
+ /**
100
+ * For annotated tags: the tag message.
101
+ * Can be multi-line with a subject and body.
102
+ */
31
103
  message?: string;
32
- /** For annotated tags with GPG signature */
104
+ /**
105
+ * For signed annotated tags: the GPG signature.
106
+ * ASCII-armored GPG signature block.
107
+ */
33
108
  signature?: string;
34
109
  }
35
110
  /**
36
- * Options for creating a tag
111
+ * Options for creating a tag.
112
+ *
113
+ * @description
114
+ * Controls tag creation behavior including whether to create
115
+ * an annotated tag, message content, and signing options.
37
116
  */
38
117
  export interface CreateTagOptions {
39
- /** Create an annotated tag (default: false for lightweight) */
118
+ /**
119
+ * Create an annotated tag (default: false for lightweight).
120
+ * If message is provided, defaults to true.
121
+ */
40
122
  annotated?: boolean;
41
- /** Tag message (required for annotated tags) */
123
+ /**
124
+ * Tag message (required for annotated tags unless using empty message).
125
+ * Can be multi-line with subject and body separated by blank line.
126
+ */
42
127
  message?: string;
43
- /** Tagger information (defaults to configured user) */
128
+ /**
129
+ * Tagger information (defaults to configured user).
130
+ * Required for annotated tags if no global config is set.
131
+ */
44
132
  tagger?: Author;
45
- /** Sign the tag with GPG */
133
+ /**
134
+ * Sign the tag with GPG.
135
+ * Requires GPGSigner to be provided to TagManager.
136
+ */
46
137
  sign?: boolean;
47
- /** GPG key ID to use for signing */
138
+ /**
139
+ * GPG key ID to use for signing.
140
+ * Defaults to the user's default signing key.
141
+ */
48
142
  keyId?: string;
49
- /** Force overwrite if tag exists */
143
+ /**
144
+ * Force overwrite if tag exists.
145
+ * Without force, creating an existing tag throws TagError.
146
+ */
50
147
  force?: boolean;
51
148
  }
52
149
  /**
53
- * Options for listing tags
150
+ * Options for listing tags.
151
+ *
152
+ * @description
153
+ * Provides filtering, sorting, and inclusion options for tag listing.
54
154
  */
55
155
  export interface ListTagsOptions {
56
- /** Pattern to filter tags (glob-like, e.g., 'v1.*') */
156
+ /**
157
+ * Pattern to filter tags (glob-like, e.g., 'v1.*', 'release-*').
158
+ * Supports * and ? wildcards.
159
+ */
57
160
  pattern?: string;
58
- /** Sort order: 'name' | 'version' | 'date' */
161
+ /**
162
+ * Sort order: 'name', 'version', or 'date'.
163
+ * 'version' uses semantic versioning comparison.
164
+ * 'date' requires includeMetadata=true for annotated tags.
165
+ */
59
166
  sort?: 'name' | 'version' | 'date';
60
- /** Sort direction */
167
+ /** Sort direction: 'asc' or 'desc' */
61
168
  sortDirection?: 'asc' | 'desc';
62
169
  /** Maximum number of tags to return */
63
170
  limit?: number;
64
- /** Include annotated tag metadata */
171
+ /**
172
+ * Include annotated tag metadata (tagger, message).
173
+ * Slower as it requires reading tag objects.
174
+ */
65
175
  includeMetadata?: boolean;
66
176
  }
67
177
  /**
68
- * Options for deleting a tag
178
+ * Options for deleting a tag.
69
179
  */
70
180
  export interface DeleteTagOptions {
71
- /** Delete even if tag doesn't exist locally */
181
+ /**
182
+ * Delete even if tag doesn't exist locally.
183
+ * Without force, deleting non-existent tag throws TagError.
184
+ */
72
185
  force?: boolean;
73
186
  }
74
187
  /**
75
- * Options for getting a tag
188
+ * Options for getting a tag.
76
189
  */
77
190
  export interface GetTagOptions {
78
- /** Resolve to get full annotated tag info */
191
+ /**
192
+ * Resolve to get full annotated tag info.
193
+ * Reads the tag object to populate tagger, message, etc.
194
+ */
79
195
  resolve?: boolean;
80
196
  }
81
197
  /**
82
- * Result of tag signature verification
198
+ * Result of tag signature verification.
199
+ *
200
+ * @description
201
+ * Contains verification status and signer information
202
+ * for signed annotated tags.
203
+ *
204
+ * @example
205
+ * ```typescript
206
+ * const result = await manager.verifyTag('v1.0.0')
207
+ * if (result.valid) {
208
+ * console.log(`Signed by: ${result.signer} (${result.keyId})`)
209
+ * console.log(`Trust: ${result.trustLevel}`)
210
+ * } else {
211
+ * console.log(`Verification failed: ${result.error}`)
212
+ * }
213
+ * ```
83
214
  */
84
215
  export interface TagSignatureVerification {
85
216
  /** Whether the signature is valid */
86
217
  valid: boolean;
87
- /** GPG key ID used for signing */
218
+ /** GPG key ID used for signing (e.g., '0x1234ABCD') */
88
219
  keyId?: string;
89
- /** Signer identity */
220
+ /** Signer identity from the key */
90
221
  signer?: string;
91
- /** Trust level of the key */
222
+ /**
223
+ * Trust level of the signing key.
224
+ * Based on GPG web of trust model.
225
+ */
92
226
  trustLevel?: 'ultimate' | 'full' | 'marginal' | 'never' | 'undefined' | 'expired' | 'unknown';
93
227
  /** Error message if verification failed */
94
228
  error?: string;
95
229
  }
96
230
  /**
97
- * Error codes specific to tag operations
231
+ * Error codes specific to tag operations.
232
+ *
233
+ * @description
234
+ * Extends RefErrorCode with tag-specific errors:
235
+ * - `TAG_EXISTS`: Tag already exists (when creating without force)
236
+ * - `TAG_NOT_FOUND`: Tag doesn't exist
237
+ * - `INVALID_TAG_NAME`: Tag name fails validation
238
+ * - `MESSAGE_REQUIRED`: Annotated tag requires a message
239
+ * - `GPG_ERROR`: GPG signing or verification failed
98
240
  */
99
241
  export type TagErrorCode = RefErrorCode | 'TAG_EXISTS' | 'TAG_NOT_FOUND' | 'INVALID_TAG_NAME' | 'MESSAGE_REQUIRED' | 'GPG_ERROR';
100
242
  /**
101
- * Error thrown when a tag operation fails
243
+ * Error thrown when a tag operation fails.
244
+ *
245
+ * @description
246
+ * Provides structured error information with error code
247
+ * for programmatic error handling.
248
+ *
249
+ * @example
250
+ * ```typescript
251
+ * try {
252
+ * await manager.createTag('v1.0.0', 'abc123')
253
+ * } catch (e) {
254
+ * if (e instanceof TagError) {
255
+ * switch (e.code) {
256
+ * case 'TAG_EXISTS':
257
+ * console.log('Tag already exists, use force=true to overwrite')
258
+ * break
259
+ * case 'MESSAGE_REQUIRED':
260
+ * console.log('Annotated tags require a message')
261
+ * break
262
+ * }
263
+ * }
264
+ * }
265
+ * ```
102
266
  */
103
267
  export declare class TagError extends Error {
104
268
  readonly code: TagErrorCode;
105
269
  readonly tagName?: string | undefined;
270
+ /**
271
+ * Create a new TagError.
272
+ *
273
+ * @param message - Human-readable error description
274
+ * @param code - Error code for programmatic handling
275
+ * @param tagName - The tag that caused the error (optional)
276
+ */
106
277
  constructor(message: string, code: TagErrorCode, tagName?: string | undefined);
107
278
  }
108
279
  /**
109
- * Storage backend interface for tag objects
280
+ * Storage backend interface for tag objects.
281
+ *
282
+ * @description
283
+ * Interface for reading and writing tag objects.
284
+ * Used by TagManager for annotated tag operations.
110
285
  */
111
286
  export interface TagObjectStorage {
112
- /** Read a tag object by SHA */
287
+ /**
288
+ * Read a tag object by SHA.
289
+ *
290
+ * @param sha - 40-character SHA-1 of the tag object
291
+ * @returns Parsed TagObject or null if not found
292
+ */
113
293
  readTagObject(sha: string): Promise<TagObject | null>;
114
- /** Write a tag object and return its SHA */
294
+ /**
295
+ * Write a tag object and return its SHA.
296
+ *
297
+ * @param tag - Tag object data (without type and data fields)
298
+ * @returns 40-character SHA-1 of the stored tag object
299
+ */
115
300
  writeTagObject(tag: Omit<TagObject, 'type' | 'data'>): Promise<string>;
116
- /** Read any object to determine its type */
301
+ /**
302
+ * Read any object to determine its type.
303
+ *
304
+ * @param sha - 40-character SHA-1 of the object
305
+ * @returns Object type or null if not found
306
+ */
117
307
  readObjectType(sha: string): Promise<ObjectType | null>;
118
308
  }
119
309
  /**
120
- * GPG signing interface
310
+ * GPG signing interface.
311
+ *
312
+ * @description
313
+ * Interface for GPG signing and verification operations.
314
+ * Used for signed tag creation and verification.
121
315
  */
122
316
  export interface GPGSigner {
123
- /** Sign data and return the signature */
317
+ /**
318
+ * Sign data and return the signature.
319
+ *
320
+ * @param data - Binary data to sign
321
+ * @param keyId - Optional specific key ID to use
322
+ * @returns ASCII-armored GPG signature
323
+ * @throws Error if signing fails
324
+ */
124
325
  sign(data: Uint8Array, keyId?: string): Promise<string>;
125
- /** Verify a signature */
326
+ /**
327
+ * Verify a signature.
328
+ *
329
+ * @param data - Binary data that was signed
330
+ * @param signature - ASCII-armored GPG signature to verify
331
+ * @returns Verification result with validity and signer info
332
+ */
126
333
  verify(data: Uint8Array, signature: string): Promise<TagSignatureVerification>;
127
334
  }
128
335
  /**
129
- * Tag manager for handling Git tag operations
336
+ * Tag manager for handling Git tag operations.
337
+ *
338
+ * @description
339
+ * Provides a comprehensive API for tag management including both
340
+ * lightweight and annotated tags. Uses RefStorage for refs and
341
+ * TagObjectStorage for tag objects.
342
+ *
343
+ * Note: Most methods are currently stubs (TODO) and will throw 'Not implemented'.
344
+ * These will be implemented in the GREEN phase of TDD development.
345
+ *
346
+ * @example
347
+ * ```typescript
348
+ * const manager = new TagManager(refStorage, objectStorage, gpgSigner)
349
+ *
350
+ * // Create a release tag
351
+ * const tag = await manager.createTag('v1.0.0', commitSha, {
352
+ * annotated: true,
353
+ * message: 'Version 1.0.0 release',
354
+ * tagger: { name: 'Alice', email: 'alice@example.com', timestamp: 1704067200, timezone: '+0000' }
355
+ * })
356
+ *
357
+ * // List version tags
358
+ * const versions = await manager.listTags({ pattern: 'v*' })
359
+ *
360
+ * // Verify signed tag
361
+ * const verification = await manager.verifyTag('v1.0.0')
362
+ * ```
130
363
  */
131
364
  export declare class TagManager {
365
+ /**
366
+ * Create a new TagManager.
367
+ *
368
+ * @param refStorage - RefStorage instance for managing tag refs
369
+ * @param objectStorage - Storage for reading/writing tag objects
370
+ * @param gpgSigner - Optional GPG signer for signed tags
371
+ */
132
372
  constructor(refStorage: RefStorage, objectStorage: TagObjectStorage, gpgSigner?: GPGSigner);
133
373
  /**
134
- * Create a new tag
374
+ * Create a new tag.
375
+ *
376
+ * @description
377
+ * Creates either a lightweight or annotated tag pointing to the
378
+ * specified target. For annotated tags, creates a tag object with
379
+ * metadata and optionally signs it.
380
+ *
381
+ * @param name - Tag name (without refs/tags/ prefix)
382
+ * @param target - Target SHA to tag (usually a commit)
383
+ * @param options - Creation options
384
+ * @returns The created tag
385
+ * @throws TagError with code 'INVALID_TAG_NAME' if name is invalid
386
+ * @throws TagError with code 'TAG_EXISTS' if tag exists and not forcing
387
+ * @throws TagError with code 'MESSAGE_REQUIRED' for annotated tag without message
388
+ * @throws TagError with code 'GPG_ERROR' if signing fails
389
+ *
390
+ * @example
391
+ * ```typescript
392
+ * // Create lightweight tag
393
+ * const light = await manager.createTag('v0.1.0', commitSha)
394
+ *
395
+ * // Create annotated tag
396
+ * const annotated = await manager.createTag('v1.0.0', commitSha, {
397
+ * annotated: true,
398
+ * message: 'Release 1.0.0',
399
+ * tagger: { name: 'Alice', email: 'alice@example.com', timestamp: 1704067200, timezone: '+0000' }
400
+ * })
401
+ *
402
+ * // Create signed tag
403
+ * const signed = await manager.createTag('v1.0.0', commitSha, {
404
+ * annotated: true,
405
+ * message: 'Release 1.0.0',
406
+ * sign: true
407
+ * })
408
+ * ```
135
409
  */
136
410
  createTag(_name: string, _target: string, _options?: CreateTagOptions): Promise<Tag>;
137
411
  /**
138
- * Delete a tag
412
+ * Delete a tag.
413
+ *
414
+ * @description
415
+ * Removes a tag ref. Does not delete the tag object (if annotated)
416
+ * as it may be referenced elsewhere (reflog, etc.).
417
+ *
418
+ * @param name - Tag name to delete
419
+ * @param options - Deletion options
420
+ * @returns True if tag was deleted, false if it didn't exist (with force)
421
+ * @throws TagError with code 'TAG_NOT_FOUND' if tag doesn't exist (without force)
422
+ *
423
+ * @example
424
+ * ```typescript
425
+ * await manager.deleteTag('v0.9.0-beta')
426
+ *
427
+ * // Delete even if doesn't exist
428
+ * await manager.deleteTag('maybe-exists', { force: true })
429
+ * ```
139
430
  */
140
431
  deleteTag(_name: string, _options?: DeleteTagOptions): Promise<boolean>;
141
432
  /**
142
- * List all tags
433
+ * List all tags.
434
+ *
435
+ * @description
436
+ * Returns tags matching the specified criteria.
437
+ * By default returns all tags sorted by name.
438
+ *
439
+ * @param options - Listing options
440
+ * @returns Array of tags matching criteria
441
+ *
442
+ * @example
443
+ * ```typescript
444
+ * // List all tags
445
+ * const all = await manager.listTags()
446
+ *
447
+ * // List version tags with metadata
448
+ * const versions = await manager.listTags({
449
+ * pattern: 'v*',
450
+ * sort: 'version',
451
+ * includeMetadata: true
452
+ * })
453
+ *
454
+ * // Get latest 5 tags
455
+ * const latest = await manager.listTags({
456
+ * sort: 'date',
457
+ * sortDirection: 'desc',
458
+ * limit: 5,
459
+ * includeMetadata: true
460
+ * })
461
+ * ```
143
462
  */
144
463
  listTags(_options?: ListTagsOptions): Promise<Tag[]>;
145
464
  /**
146
- * Get a tag by name
465
+ * Get a tag by name.
466
+ *
467
+ * @description
468
+ * Retrieves tag information. Use resolve=true to get full
469
+ * annotated tag metadata.
470
+ *
471
+ * @param name - Tag name
472
+ * @param options - Get options
473
+ * @returns Tag info or null if not found
474
+ *
475
+ * @example
476
+ * ```typescript
477
+ * // Quick lookup
478
+ * const tag = await manager.getTag('v1.0.0')
479
+ *
480
+ * // Get full metadata
481
+ * const full = await manager.getTag('v1.0.0', { resolve: true })
482
+ * if (full?.type === 'annotated') {
483
+ * console.log(`Tagged by: ${full.tagger?.name}`)
484
+ * console.log(`Message: ${full.message}`)
485
+ * }
486
+ * ```
147
487
  */
148
488
  getTag(_name: string, _options?: GetTagOptions): Promise<Tag | null>;
149
489
  /**
150
- * Check if a tag exists
490
+ * Check if a tag exists.
491
+ *
492
+ * @description
493
+ * Quick check for tag existence without fetching full info.
494
+ *
495
+ * @param name - Tag name
496
+ * @returns True if tag exists
497
+ *
498
+ * @example
499
+ * ```typescript
500
+ * if (await manager.tagExists('v1.0.0')) {
501
+ * console.log('Tag already exists')
502
+ * }
503
+ * ```
151
504
  */
152
505
  tagExists(_name: string): Promise<boolean>;
153
506
  /**
154
- * Get the target (commit SHA) that a tag points to
507
+ * Get the target (commit SHA) that a tag points to.
508
+ *
509
+ * @description
510
+ * Resolves through annotated tags to get the final target.
511
+ * For lightweight tags, returns the sha directly.
512
+ * For annotated tags, returns the targetSha.
513
+ *
514
+ * @param name - Tag name
515
+ * @returns Target commit SHA
516
+ * @throws TagError with code 'TAG_NOT_FOUND' if tag doesn't exist
517
+ *
518
+ * @example
519
+ * ```typescript
520
+ * const commitSha = await manager.getTagTarget('v1.0.0')
521
+ * ```
155
522
  */
156
523
  getTagTarget(_name: string): Promise<string>;
157
524
  /**
158
- * Verify a tag's GPG signature
525
+ * Verify a tag's GPG signature.
526
+ *
527
+ * @description
528
+ * Verifies the GPG signature on a signed annotated tag.
529
+ * Returns verification result with signer info.
530
+ *
531
+ * @param name - Tag name to verify
532
+ * @returns Verification result
533
+ * @throws TagError with code 'TAG_NOT_FOUND' if tag doesn't exist
534
+ *
535
+ * @example
536
+ * ```typescript
537
+ * const result = await manager.verifyTag('v1.0.0')
538
+ * if (result.valid) {
539
+ * console.log(`Signed by: ${result.signer}`)
540
+ * console.log(`Trust: ${result.trustLevel}`)
541
+ * } else {
542
+ * console.log(`Verification failed: ${result.error}`)
543
+ * }
544
+ * ```
159
545
  */
160
546
  verifyTag(_name: string): Promise<TagSignatureVerification>;
161
547
  /**
162
- * Check if a tag is annotated
548
+ * Check if a tag is annotated.
549
+ *
550
+ * @description
551
+ * Determines if a tag is annotated (has a tag object) or lightweight.
552
+ *
553
+ * @param name - Tag name
554
+ * @returns True if the tag is annotated
555
+ * @throws TagError with code 'TAG_NOT_FOUND' if tag doesn't exist
556
+ *
557
+ * @example
558
+ * ```typescript
559
+ * if (await manager.isAnnotatedTag('v1.0.0')) {
560
+ * console.log('This is an annotated tag')
561
+ * }
562
+ * ```
163
563
  */
164
564
  isAnnotatedTag(_name: string): Promise<boolean>;
165
565
  }
166
566
  /**
167
- * Validate a tag name according to Git rules
168
- * Similar to ref name rules but with tag-specific constraints
567
+ * Validate a tag name according to Git rules.
568
+ *
569
+ * @description
570
+ * Tags follow the same rules as refs but under refs/tags/.
571
+ * This validates against the full git-check-ref-format rules.
572
+ *
573
+ * **Rules**:
574
+ * - Cannot be empty
575
+ * - Cannot end with '/' or '.lock'
576
+ * - Cannot contain '..', '@{', control chars, space, ~, ^, :, ?, *, [, \
577
+ * - Components cannot start or end with '.'
578
+ *
579
+ * Note: This is a stub implementation. Full validation will be added in GREEN phase.
580
+ *
581
+ * @param name - Tag name to validate
582
+ * @returns True if valid
583
+ *
584
+ * @see https://git-scm.com/docs/git-check-ref-format
585
+ *
586
+ * @example
587
+ * ```typescript
588
+ * isValidTagName('v1.0.0') // true
589
+ * isValidTagName('release/1.0') // true
590
+ * isValidTagName('v1.0.0.lock') // false (ends with .lock)
591
+ * isValidTagName('v1..0') // false (contains ..)
592
+ * isValidTagName('') // false (empty)
593
+ * ```
169
594
  */
170
595
  export declare function isValidTagName(_name: string): boolean;
171
596
  /**
172
- * Check if a string is a valid annotated tag (has tag object)
597
+ * Type guard for annotated tags.
598
+ *
599
+ * @description
600
+ * Checks if a tag is annotated with full metadata.
601
+ * Narrows the type to include tagger and message.
602
+ *
603
+ * @param tag - Tag to check
604
+ * @returns True if the tag is annotated with full metadata
605
+ *
606
+ * @example
607
+ * ```typescript
608
+ * if (isAnnotatedTag(tag)) {
609
+ * // tag.tagger and tag.message are now guaranteed
610
+ * console.log(`Tagged by: ${tag.tagger.name}`)
611
+ * }
612
+ * ```
173
613
  */
174
614
  export declare function isAnnotatedTag(_tag: Tag): _tag is Tag & {
175
615
  type: 'annotated';
@@ -177,54 +617,224 @@ export declare function isAnnotatedTag(_tag: Tag): _tag is Tag & {
177
617
  message: string;
178
618
  };
179
619
  /**
180
- * Format a tag message (handle line endings, etc.)
620
+ * Format a tag message.
621
+ *
622
+ * @description
623
+ * Normalizes a tag message: handles line endings, trims whitespace,
624
+ * ensures proper formatting.
625
+ *
626
+ * @param message - Raw message input
627
+ * @returns Formatted message
628
+ *
629
+ * @example
630
+ * ```typescript
631
+ * formatTagMessage(' Hello World \r\n') // 'Hello World\n'
632
+ * ```
181
633
  */
182
634
  export declare function formatTagMessage(_message: string): string;
183
635
  /**
184
- * Parse a tag message from raw content
636
+ * Parse a tag message from raw content.
637
+ *
638
+ * @description
639
+ * Separates the message from any GPG signature.
640
+ * GPG signatures start with '-----BEGIN PGP SIGNATURE-----'.
641
+ *
642
+ * @param content - Raw tag content
643
+ * @returns Parsed message and optional signature
644
+ *
645
+ * @example
646
+ * ```typescript
647
+ * const { message, signature } = parseTagMessage(content)
648
+ * if (signature) {
649
+ * console.log('Tag is signed')
650
+ * }
651
+ * ```
185
652
  */
186
653
  export declare function parseTagMessage(_content: string): {
187
654
  message: string;
188
655
  signature?: string;
189
656
  };
190
657
  /**
191
- * Create a lightweight tag pointing to a commit
658
+ * Create a tag (lightweight or annotated).
659
+ *
660
+ * @description
661
+ * Convenience function that wraps TagManager.createTag.
662
+ *
663
+ * @param manager - TagManager instance
664
+ * @param name - Tag name
665
+ * @param target - Target SHA to tag
666
+ * @param options - Creation options
667
+ * @returns Created tag
668
+ *
669
+ * @example
670
+ * ```typescript
671
+ * const tag = await createTag(manager, 'v1.0.0', commitSha, {
672
+ * annotated: true,
673
+ * message: 'Release 1.0.0'
674
+ * })
675
+ * ```
192
676
  */
193
677
  export declare function createTag(_manager: TagManager, _name: string, _target: string, _options?: CreateTagOptions): Promise<Tag>;
194
678
  /**
195
- * Create an annotated tag with message
679
+ * Create an annotated tag with message.
680
+ *
681
+ * @description
682
+ * Convenience function for creating annotated tags.
683
+ * Automatically sets annotated=true.
684
+ *
685
+ * @param manager - TagManager instance
686
+ * @param name - Tag name
687
+ * @param target - Target SHA to tag
688
+ * @param message - Tag message
689
+ * @param tagger - Tagger information
690
+ * @param options - Additional options (excluding annotated, message, tagger)
691
+ * @returns Created annotated tag
692
+ *
693
+ * @example
694
+ * ```typescript
695
+ * const tag = await createAnnotatedTag(
696
+ * manager,
697
+ * 'v1.0.0',
698
+ * commitSha,
699
+ * 'Release 1.0.0',
700
+ * { name: 'Alice', email: 'alice@example.com', timestamp: Date.now()/1000, timezone: '+0000' }
701
+ * )
702
+ * ```
196
703
  */
197
704
  export declare function createAnnotatedTag(_manager: TagManager, _name: string, _target: string, _message: string, _tagger: Author, _options?: Omit<CreateTagOptions, 'annotated' | 'message' | 'tagger'>): Promise<Tag>;
198
705
  /**
199
- * Delete a tag
706
+ * Delete a tag.
707
+ *
708
+ * @description
709
+ * Convenience function that wraps TagManager.deleteTag.
710
+ *
711
+ * @param manager - TagManager instance
712
+ * @param name - Tag name to delete
713
+ * @param options - Deletion options
714
+ * @returns True if deleted
715
+ *
716
+ * @example
717
+ * ```typescript
718
+ * await deleteTag(manager, 'v0.9.0-beta')
719
+ * ```
200
720
  */
201
721
  export declare function deleteTag(_manager: TagManager, _name: string, _options?: DeleteTagOptions): Promise<boolean>;
202
722
  /**
203
- * List all tags
723
+ * List all tags.
724
+ *
725
+ * @description
726
+ * Convenience function that wraps TagManager.listTags.
727
+ *
728
+ * @param manager - TagManager instance
729
+ * @param options - Listing options
730
+ * @returns Array of tags
731
+ *
732
+ * @example
733
+ * ```typescript
734
+ * const tags = await listTags(manager, { pattern: 'v1.*' })
735
+ * ```
204
736
  */
205
737
  export declare function listTags(_manager: TagManager, _options?: ListTagsOptions): Promise<Tag[]>;
206
738
  /**
207
- * Get a tag by name
739
+ * Get a tag by name.
740
+ *
741
+ * @description
742
+ * Convenience function that wraps TagManager.getTag.
743
+ *
744
+ * @param manager - TagManager instance
745
+ * @param name - Tag name
746
+ * @param options - Get options
747
+ * @returns Tag info or null
748
+ *
749
+ * @example
750
+ * ```typescript
751
+ * const tag = await getTag(manager, 'v1.0.0', { resolve: true })
752
+ * ```
208
753
  */
209
754
  export declare function getTag(_manager: TagManager, _name: string, _options?: GetTagOptions): Promise<Tag | null>;
210
755
  /**
211
- * Check if a tag is an annotated tag
756
+ * Check if a tag is annotated.
757
+ *
758
+ * @description
759
+ * Convenience function that wraps TagManager.isAnnotatedTag.
760
+ *
761
+ * @param manager - TagManager instance
762
+ * @param name - Tag name
763
+ * @returns True if annotated
764
+ *
765
+ * @example
766
+ * ```typescript
767
+ * if (await checkIsAnnotatedTag(manager, 'v1.0.0')) {
768
+ * console.log('Annotated tag')
769
+ * }
770
+ * ```
212
771
  */
213
772
  export declare function checkIsAnnotatedTag(_manager: TagManager, _name: string): Promise<boolean>;
214
773
  /**
215
- * Verify a tag's signature
774
+ * Verify a tag's signature.
775
+ *
776
+ * @description
777
+ * Convenience function that wraps TagManager.verifyTag.
778
+ *
779
+ * @param manager - TagManager instance
780
+ * @param name - Tag name
781
+ * @returns Verification result
782
+ *
783
+ * @example
784
+ * ```typescript
785
+ * const result = await verifyTagSignature(manager, 'v1.0.0')
786
+ * ```
216
787
  */
217
788
  export declare function verifyTagSignature(_manager: TagManager, _name: string): Promise<TagSignatureVerification>;
218
789
  /**
219
- * Get the target commit SHA for a tag
790
+ * Get the target commit SHA for a tag.
791
+ *
792
+ * @description
793
+ * Convenience function that wraps TagManager.getTagTarget.
794
+ *
795
+ * @param manager - TagManager instance
796
+ * @param name - Tag name
797
+ * @returns Target commit SHA
798
+ *
799
+ * @example
800
+ * ```typescript
801
+ * const sha = await getTagTarget(manager, 'v1.0.0')
802
+ * ```
220
803
  */
221
804
  export declare function getTagTarget(_manager: TagManager, _name: string): Promise<string>;
222
805
  /**
223
- * Sort tags by semantic version
806
+ * Sort tags by semantic version.
807
+ *
808
+ * @description
809
+ * Sorts tags that look like semantic versions (v1.2.3).
810
+ * Non-semver tags are sorted lexicographically at the end.
811
+ *
812
+ * @param tags - Array of tags to sort
813
+ * @param direction - Sort direction ('asc' or 'desc')
814
+ * @returns Sorted array of tags
815
+ *
816
+ * @example
817
+ * ```typescript
818
+ * const sorted = sortTagsByVersion(tags, 'desc')
819
+ * // ['v2.0.0', 'v1.10.0', 'v1.9.0', 'v1.0.0', ...]
820
+ * ```
224
821
  */
225
822
  export declare function sortTagsByVersion(_tags: Tag[], _direction?: 'asc' | 'desc'): Tag[];
226
823
  /**
227
- * Filter tags by glob pattern
824
+ * Filter tags by glob pattern.
825
+ *
826
+ * @description
827
+ * Filters tags matching a glob pattern.
828
+ * Supports * (any chars) and ? (single char) wildcards.
829
+ *
830
+ * @param tags - Array of tags to filter
831
+ * @param pattern - Glob pattern (e.g., 'v1.*', 'release-*')
832
+ * @returns Filtered array of tags
833
+ *
834
+ * @example
835
+ * ```typescript
836
+ * const v1Tags = filterTagsByPattern(tags, 'v1.*')
837
+ * ```
228
838
  */
229
839
  export declare function filterTagsByPattern(_tags: Tag[], _pattern: string): Tag[];
230
840
  //# sourceMappingURL=tag.d.ts.map