@optique/git 1.0.0-dev.908 → 1.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.
package/dist/index.cjs CHANGED
@@ -126,8 +126,9 @@ function createAsyncValueParser(options, metavar, parseFn, suggestFn) {
126
126
  }
127
127
  const validatedDepth = options?.suggestionDepth ?? DEFAULT_SUGGESTION_DEPTH;
128
128
  return {
129
- $mode: "async",
129
+ mode: "async",
130
130
  metavar,
131
+ placeholder: "",
131
132
  parse(input) {
132
133
  const dir = getRepoDir(options?.dir);
133
134
  return parseFn(dir, input, options?.errors);
@@ -178,7 +179,7 @@ function gitBranch(options) {
178
179
  };
179
180
  return {
180
181
  success: false,
181
- error: __optique_core_message.message`Branch ${(0, __optique_core_message.value)(input)} does not exist. Available branches: ${(0, __optique_core_message.valueSet)(branches)}`
182
+ error: __optique_core_message.message`Branch ${(0, __optique_core_message.value)(input)} does not exist.${branches.length > 0 ? __optique_core_message.message` Available branches: ${(0, __optique_core_message.valueSet)(branches, "")}` : __optique_core_message.message``}`
182
183
  };
183
184
  } catch (error) {
184
185
  const fallback = __optique_core_message.message`Failed to list branches. Ensure ${(0, __optique_core_message.value)(dir)} is a valid git repository.`;
@@ -215,6 +216,8 @@ function gitBranch(options) {
215
216
  * @param remote The remote name to validate against.
216
217
  * @param options Configuration options for the parser.
217
218
  * @returns A value parser that accepts existing remote branch names.
219
+ * @throws {TypeError} If `remote` is not a valid non-empty string without
220
+ * whitespace or control characters.
218
221
  * @throws {RangeError} If `suggestionDepth` is not a positive integer.
219
222
  * @since 0.9.0
220
223
  *
@@ -227,6 +230,9 @@ function gitBranch(options) {
227
230
  * ~~~~
228
231
  */
229
232
  function gitRemoteBranch(remote, options) {
233
+ const expectedMessage = "Expected remote to be a non-empty string without whitespace or control characters";
234
+ if (typeof remote !== "string") throw new TypeError(`${expectedMessage}, but got: ${remote === null ? "null" : Array.isArray(remote) ? "array" : typeof remote}.`);
235
+ if (remote === "" || /[\s\x00-\x1f]/.test(remote)) throw new TypeError(`${expectedMessage}, but got: ${JSON.stringify(remote)}.`);
230
236
  const metavar = options?.metavar ?? METAVAR_BRANCH;
231
237
  return createAsyncValueParser(options, metavar, async (dir, input, errors) => {
232
238
  try {
@@ -239,13 +245,34 @@ function gitRemoteBranch(remote, options) {
239
245
  success: true,
240
246
  value: input
241
247
  };
248
+ if (branches.length === 0) {
249
+ const remotes = await isomorphic_git.listRemotes({
250
+ fs: gitFs,
251
+ dir
252
+ });
253
+ const names = remotes.map((r) => r.remote);
254
+ if (!names.includes(remote)) {
255
+ if (errors?.remoteNotFound) return {
256
+ success: false,
257
+ error: errors.remoteNotFound(remote, names)
258
+ };
259
+ if (errors?.notFound) return {
260
+ success: false,
261
+ error: errors.notFound(input, branches)
262
+ };
263
+ return {
264
+ success: false,
265
+ error: __optique_core_message.message`Remote ${(0, __optique_core_message.value)(remote)} does not exist.${names.length > 0 ? __optique_core_message.message` Available remotes: ${(0, __optique_core_message.valueSet)(names, "")}` : __optique_core_message.message``}`
266
+ };
267
+ }
268
+ }
242
269
  if (errors?.notFound) return {
243
270
  success: false,
244
271
  error: errors.notFound(input, branches)
245
272
  };
246
273
  return {
247
274
  success: false,
248
- error: __optique_core_message.message`Remote branch ${(0, __optique_core_message.value)(input)} does not exist on remote ${(0, __optique_core_message.value)(remote)}. Available branches: ${(0, __optique_core_message.valueSet)(branches)}`
275
+ error: __optique_core_message.message`Remote branch ${(0, __optique_core_message.value)(input)} does not exist on remote ${(0, __optique_core_message.value)(remote)}.${branches.length > 0 ? __optique_core_message.message` Available branches: ${(0, __optique_core_message.valueSet)(branches, "")}` : __optique_core_message.message``}`
249
276
  };
250
277
  } catch (error) {
251
278
  const fallback = __optique_core_message.message`Failed to list remote branches. Ensure remote ${(0, __optique_core_message.value)(remote)} exists.`;
@@ -301,7 +328,7 @@ function gitTag(options) {
301
328
  };
302
329
  return {
303
330
  success: false,
304
- error: __optique_core_message.message`Tag ${(0, __optique_core_message.value)(input)} does not exist. Available tags: ${(0, __optique_core_message.valueSet)(tags)}`
331
+ error: __optique_core_message.message`Tag ${(0, __optique_core_message.value)(input)} does not exist.${tags.length > 0 ? __optique_core_message.message` Available tags: ${(0, __optique_core_message.valueSet)(tags, "")}` : __optique_core_message.message``}`
305
332
  };
306
333
  } catch (error) {
307
334
  const fallback = __optique_core_message.message`Failed to list tags. Ensure ${(0, __optique_core_message.value)(dir)} is a valid git repository.`;
@@ -356,7 +383,7 @@ function gitRemote(options) {
356
383
  };
357
384
  return {
358
385
  success: false,
359
- error: __optique_core_message.message`Remote ${(0, __optique_core_message.value)(input)} does not exist. Available remotes: ${(0, __optique_core_message.valueSet)(names)}`
386
+ error: __optique_core_message.message`Remote ${(0, __optique_core_message.value)(input)} does not exist.${names.length > 0 ? __optique_core_message.message` Available remotes: ${(0, __optique_core_message.valueSet)(names, "")}` : __optique_core_message.message``}`
360
387
  };
361
388
  } catch (error) {
362
389
  const fallback = __optique_core_message.message`Failed to list remotes. Ensure ${(0, __optique_core_message.value)(dir)} is a valid git repository.`;
@@ -571,7 +598,8 @@ function gitRef(options) {
571
598
  * @param options Shared configuration for the parsers.
572
599
  * @returns An object containing git parsers. Each returned method may throw
573
600
  * a {@link RangeError} if the merged `suggestionDepth` is not a positive
574
- * integer.
601
+ * integer. `remoteBranch()` may also throw a {@link TypeError} if `remote`
602
+ * is not a valid non-empty string without whitespace or control characters.
575
603
  * @since 0.9.0
576
604
  */
577
605
  function createGitParsers(options) {
package/dist/index.d.cts CHANGED
@@ -68,6 +68,16 @@ interface GitParserErrors {
68
68
  * @returns A custom error message.
69
69
  */
70
70
  invalidFormat?: (input: string) => Message;
71
+ /**
72
+ * Error message when the remote does not exist.
73
+ * Only used by {@link gitRemoteBranch}.
74
+ *
75
+ * @param remote The remote name that was not found.
76
+ * @param availableRemotes List of available remote names.
77
+ * @returns A custom error message.
78
+ * @since 1.0.0
79
+ */
80
+ remoteNotFound?: (remote: string, availableRemotes: readonly string[]) => Message;
71
81
  }
72
82
  /**
73
83
  * Git parsers factory interface.
@@ -87,6 +97,8 @@ interface GitParsers {
87
97
  * @param remote The remote name to validate against.
88
98
  * @param options Configuration options for the parser.
89
99
  * @returns A value parser that accepts existing remote branch names.
100
+ * @throws {TypeError} If `remote` is not a valid non-empty string without
101
+ * whitespace or control characters.
90
102
  * @throws {RangeError} If `suggestionDepth` is not a positive integer.
91
103
  */
92
104
  remoteBranch(remote: string, options?: GitParserOptions): ValueParser<"async", string>;
@@ -149,6 +161,8 @@ declare function gitBranch(options?: GitParserOptions): ValueParser<"async", str
149
161
  * @param remote The remote name to validate against.
150
162
  * @param options Configuration options for the parser.
151
163
  * @returns A value parser that accepts existing remote branch names.
164
+ * @throws {TypeError} If `remote` is not a valid non-empty string without
165
+ * whitespace or control characters.
152
166
  * @throws {RangeError} If `suggestionDepth` is not a positive integer.
153
167
  * @since 0.9.0
154
168
  *
@@ -209,7 +223,8 @@ declare function gitRef(options?: GitParserOptions): ValueParser<"async", string
209
223
  * @param options Shared configuration for the parsers.
210
224
  * @returns An object containing git parsers. Each returned method may throw
211
225
  * a {@link RangeError} if the merged `suggestionDepth` is not a positive
212
- * integer.
226
+ * integer. `remoteBranch()` may also throw a {@link TypeError} if `remote`
227
+ * is not a valid non-empty string without whitespace or control characters.
213
228
  * @since 0.9.0
214
229
  */
215
230
  declare function createGitParsers(options?: GitParserOptions): GitParsers;
package/dist/index.d.ts CHANGED
@@ -68,6 +68,16 @@ interface GitParserErrors {
68
68
  * @returns A custom error message.
69
69
  */
70
70
  invalidFormat?: (input: string) => Message;
71
+ /**
72
+ * Error message when the remote does not exist.
73
+ * Only used by {@link gitRemoteBranch}.
74
+ *
75
+ * @param remote The remote name that was not found.
76
+ * @param availableRemotes List of available remote names.
77
+ * @returns A custom error message.
78
+ * @since 1.0.0
79
+ */
80
+ remoteNotFound?: (remote: string, availableRemotes: readonly string[]) => Message;
71
81
  }
72
82
  /**
73
83
  * Git parsers factory interface.
@@ -87,6 +97,8 @@ interface GitParsers {
87
97
  * @param remote The remote name to validate against.
88
98
  * @param options Configuration options for the parser.
89
99
  * @returns A value parser that accepts existing remote branch names.
100
+ * @throws {TypeError} If `remote` is not a valid non-empty string without
101
+ * whitespace or control characters.
90
102
  * @throws {RangeError} If `suggestionDepth` is not a positive integer.
91
103
  */
92
104
  remoteBranch(remote: string, options?: GitParserOptions): ValueParser<"async", string>;
@@ -149,6 +161,8 @@ declare function gitBranch(options?: GitParserOptions): ValueParser<"async", str
149
161
  * @param remote The remote name to validate against.
150
162
  * @param options Configuration options for the parser.
151
163
  * @returns A value parser that accepts existing remote branch names.
164
+ * @throws {TypeError} If `remote` is not a valid non-empty string without
165
+ * whitespace or control characters.
152
166
  * @throws {RangeError} If `suggestionDepth` is not a positive integer.
153
167
  * @since 0.9.0
154
168
  *
@@ -209,7 +223,8 @@ declare function gitRef(options?: GitParserOptions): ValueParser<"async", string
209
223
  * @param options Shared configuration for the parsers.
210
224
  * @returns An object containing git parsers. Each returned method may throw
211
225
  * a {@link RangeError} if the merged `suggestionDepth` is not a positive
212
- * integer.
226
+ * integer. `remoteBranch()` may also throw a {@link TypeError} if `remote`
227
+ * is not a valid non-empty string without whitespace or control characters.
213
228
  * @since 0.9.0
214
229
  */
215
230
  declare function createGitParsers(options?: GitParserOptions): GitParsers;
package/dist/index.js CHANGED
@@ -104,8 +104,9 @@ function createAsyncValueParser(options, metavar, parseFn, suggestFn) {
104
104
  }
105
105
  const validatedDepth = options?.suggestionDepth ?? DEFAULT_SUGGESTION_DEPTH;
106
106
  return {
107
- $mode: "async",
107
+ mode: "async",
108
108
  metavar,
109
+ placeholder: "",
109
110
  parse(input) {
110
111
  const dir = getRepoDir(options?.dir);
111
112
  return parseFn(dir, input, options?.errors);
@@ -156,7 +157,7 @@ function gitBranch(options) {
156
157
  };
157
158
  return {
158
159
  success: false,
159
- error: message`Branch ${value(input)} does not exist. Available branches: ${valueSet(branches)}`
160
+ error: message`Branch ${value(input)} does not exist.${branches.length > 0 ? message` Available branches: ${valueSet(branches, "")}` : message``}`
160
161
  };
161
162
  } catch (error) {
162
163
  const fallback = message`Failed to list branches. Ensure ${value(dir)} is a valid git repository.`;
@@ -193,6 +194,8 @@ function gitBranch(options) {
193
194
  * @param remote The remote name to validate against.
194
195
  * @param options Configuration options for the parser.
195
196
  * @returns A value parser that accepts existing remote branch names.
197
+ * @throws {TypeError} If `remote` is not a valid non-empty string without
198
+ * whitespace or control characters.
196
199
  * @throws {RangeError} If `suggestionDepth` is not a positive integer.
197
200
  * @since 0.9.0
198
201
  *
@@ -205,6 +208,9 @@ function gitBranch(options) {
205
208
  * ~~~~
206
209
  */
207
210
  function gitRemoteBranch(remote, options) {
211
+ const expectedMessage = "Expected remote to be a non-empty string without whitespace or control characters";
212
+ if (typeof remote !== "string") throw new TypeError(`${expectedMessage}, but got: ${remote === null ? "null" : Array.isArray(remote) ? "array" : typeof remote}.`);
213
+ if (remote === "" || /[\s\x00-\x1f]/.test(remote)) throw new TypeError(`${expectedMessage}, but got: ${JSON.stringify(remote)}.`);
208
214
  const metavar = options?.metavar ?? METAVAR_BRANCH;
209
215
  return createAsyncValueParser(options, metavar, async (dir, input, errors) => {
210
216
  try {
@@ -217,13 +223,34 @@ function gitRemoteBranch(remote, options) {
217
223
  success: true,
218
224
  value: input
219
225
  };
226
+ if (branches.length === 0) {
227
+ const remotes = await git.listRemotes({
228
+ fs: gitFs,
229
+ dir
230
+ });
231
+ const names = remotes.map((r) => r.remote);
232
+ if (!names.includes(remote)) {
233
+ if (errors?.remoteNotFound) return {
234
+ success: false,
235
+ error: errors.remoteNotFound(remote, names)
236
+ };
237
+ if (errors?.notFound) return {
238
+ success: false,
239
+ error: errors.notFound(input, branches)
240
+ };
241
+ return {
242
+ success: false,
243
+ error: message`Remote ${value(remote)} does not exist.${names.length > 0 ? message` Available remotes: ${valueSet(names, "")}` : message``}`
244
+ };
245
+ }
246
+ }
220
247
  if (errors?.notFound) return {
221
248
  success: false,
222
249
  error: errors.notFound(input, branches)
223
250
  };
224
251
  return {
225
252
  success: false,
226
- error: message`Remote branch ${value(input)} does not exist on remote ${value(remote)}. Available branches: ${valueSet(branches)}`
253
+ error: message`Remote branch ${value(input)} does not exist on remote ${value(remote)}.${branches.length > 0 ? message` Available branches: ${valueSet(branches, "")}` : message``}`
227
254
  };
228
255
  } catch (error) {
229
256
  const fallback = message`Failed to list remote branches. Ensure remote ${value(remote)} exists.`;
@@ -279,7 +306,7 @@ function gitTag(options) {
279
306
  };
280
307
  return {
281
308
  success: false,
282
- error: message`Tag ${value(input)} does not exist. Available tags: ${valueSet(tags)}`
309
+ error: message`Tag ${value(input)} does not exist.${tags.length > 0 ? message` Available tags: ${valueSet(tags, "")}` : message``}`
283
310
  };
284
311
  } catch (error) {
285
312
  const fallback = message`Failed to list tags. Ensure ${value(dir)} is a valid git repository.`;
@@ -334,7 +361,7 @@ function gitRemote(options) {
334
361
  };
335
362
  return {
336
363
  success: false,
337
- error: message`Remote ${value(input)} does not exist. Available remotes: ${valueSet(names)}`
364
+ error: message`Remote ${value(input)} does not exist.${names.length > 0 ? message` Available remotes: ${valueSet(names, "")}` : message``}`
338
365
  };
339
366
  } catch (error) {
340
367
  const fallback = message`Failed to list remotes. Ensure ${value(dir)} is a valid git repository.`;
@@ -549,7 +576,8 @@ function gitRef(options) {
549
576
  * @param options Shared configuration for the parsers.
550
577
  * @returns An object containing git parsers. Each returned method may throw
551
578
  * a {@link RangeError} if the merged `suggestionDepth` is not a positive
552
- * integer.
579
+ * integer. `remoteBranch()` may also throw a {@link TypeError} if `remote`
580
+ * is not a valid non-empty string without whitespace or control characters.
553
581
  * @since 0.9.0
554
582
  */
555
583
  function createGitParsers(options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@optique/git",
3
- "version": "1.0.0-dev.908+f60f037d",
3
+ "version": "1.0.0",
4
4
  "description": "Git value parsers for Optique",
5
5
  "keywords": [
6
6
  "CLI",
@@ -57,9 +57,9 @@
57
57
  },
58
58
  "sideEffects": false,
59
59
  "dependencies": {
60
- "@logtape/logtape": "^1.2.2",
60
+ "@logtape/logtape": "^2.0.4",
61
61
  "isomorphic-git": "^1.36.1",
62
- "@optique/core": "1.0.0-dev.908+f60f037d"
62
+ "@optique/core": "1.0.0"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@types/node": "^20.19.9",