effect 4.0.0-beta.13 → 4.0.0-beta.15
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/Channel.d.ts +6 -6
- package/dist/Channel.d.ts.map +1 -1
- package/dist/Channel.js +4 -4
- package/dist/Channel.js.map +1 -1
- package/dist/Effect.d.ts +7 -7
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js.map +1 -1
- package/dist/Stream.d.ts +7 -7
- package/dist/Stream.d.ts.map +1 -1
- package/dist/Stream.js +8 -6
- package/dist/Stream.js.map +1 -1
- package/dist/Types.d.ts +70 -0
- package/dist/Types.d.ts.map +1 -1
- package/dist/internal/effect.js +4 -4
- package/dist/internal/effect.js.map +1 -1
- package/dist/unstable/ai/LanguageModel.d.ts +2 -0
- package/dist/unstable/ai/LanguageModel.d.ts.map +1 -1
- package/dist/unstable/ai/LanguageModel.js.map +1 -1
- package/dist/unstable/cli/Command.d.ts +34 -4
- package/dist/unstable/cli/Command.d.ts.map +1 -1
- package/dist/unstable/cli/Command.js +75 -20
- package/dist/unstable/cli/Command.js.map +1 -1
- package/dist/unstable/cli/GlobalFlag.d.ts +25 -62
- package/dist/unstable/cli/GlobalFlag.d.ts.map +1 -1
- package/dist/unstable/cli/GlobalFlag.js +41 -87
- package/dist/unstable/cli/GlobalFlag.js.map +1 -1
- package/dist/unstable/cli/internal/command.d.ts +3 -0
- package/dist/unstable/cli/internal/command.d.ts.map +1 -1
- package/dist/unstable/cli/internal/command.js +2 -0
- package/dist/unstable/cli/internal/command.js.map +1 -1
- package/dist/unstable/cli/internal/help.d.ts +18 -4
- package/dist/unstable/cli/internal/help.d.ts.map +1 -1
- package/dist/unstable/cli/internal/help.js +62 -9
- package/dist/unstable/cli/internal/help.js.map +1 -1
- package/dist/unstable/httpapi/HttpApiBuilder.d.ts +10 -4
- package/dist/unstable/httpapi/HttpApiBuilder.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApiBuilder.js +17 -6
- package/dist/unstable/httpapi/HttpApiBuilder.js.map +1 -1
- package/dist/unstable/httpapi/HttpApiEndpoint.d.ts +7 -2
- package/dist/unstable/httpapi/HttpApiEndpoint.d.ts.map +1 -1
- package/dist/unstable/httpapi/HttpApiEndpoint.js.map +1 -1
- package/dist/unstable/httpapi/OpenApi.d.ts.map +1 -1
- package/dist/unstable/httpapi/OpenApi.js +3 -4
- package/dist/unstable/httpapi/OpenApi.js.map +1 -1
- package/dist/unstable/reactivity/AtomHttpApi.d.ts +2 -2
- package/dist/unstable/reactivity/AtomHttpApi.d.ts.map +1 -1
- package/dist/unstable/reactivity/AtomRegistry.js +2 -6
- package/dist/unstable/reactivity/AtomRegistry.js.map +1 -1
- package/package.json +1 -1
- package/src/Channel.ts +24 -14
- package/src/Effect.ts +30 -8
- package/src/Stream.ts +46 -22
- package/src/Types.ts +66 -0
- package/src/internal/effect.ts +41 -14
- package/src/unstable/ai/LanguageModel.ts +9 -6
- package/src/unstable/cli/Command.ts +122 -24
- package/src/unstable/cli/GlobalFlag.ts +98 -197
- package/src/unstable/cli/internal/command.ts +5 -0
- package/src/unstable/cli/internal/help.ts +104 -24
- package/src/unstable/httpapi/HttpApiBuilder.ts +68 -13
- package/src/unstable/httpapi/HttpApiEndpoint.ts +13 -4
- package/src/unstable/httpapi/OpenApi.ts +3 -4
- package/src/unstable/reactivity/AtomHttpApi.ts +2 -2
- package/src/unstable/reactivity/AtomRegistry.ts +2 -6
|
@@ -4,11 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import * as Console from "../../Console.ts"
|
|
6
6
|
import * as Effect from "../../Effect.ts"
|
|
7
|
-
import {
|
|
8
|
-
import * as Layer from "../../Layer.ts"
|
|
9
|
-
import type { LogLevel } from "../../LogLevel.ts"
|
|
7
|
+
import type { LogLevel as LogLevelType } from "../../LogLevel.ts"
|
|
10
8
|
import * as Option from "../../Option.ts"
|
|
11
|
-
import * as References from "../../References.ts"
|
|
12
9
|
import * as ServiceMap from "../../ServiceMap.ts"
|
|
13
10
|
import * as CliOutput from "./CliOutput.ts"
|
|
14
11
|
import type * as Command from "./Command.ts"
|
|
@@ -51,10 +48,21 @@ export interface Action<A> {
|
|
|
51
48
|
* @since 4.0.0
|
|
52
49
|
* @category models
|
|
53
50
|
*/
|
|
54
|
-
export interface Setting<A> {
|
|
51
|
+
export interface Setting<Id extends string, A> extends ServiceMap.Service<Setting.Identifier<Id>, A> {
|
|
55
52
|
readonly _tag: "Setting"
|
|
53
|
+
readonly id: Id
|
|
56
54
|
readonly flag: Flag.Flag<A>
|
|
57
|
-
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @since 4.0.0
|
|
59
|
+
*/
|
|
60
|
+
export declare namespace Setting {
|
|
61
|
+
/**
|
|
62
|
+
* @since 4.0.0
|
|
63
|
+
* @category models
|
|
64
|
+
*/
|
|
65
|
+
export type Identifier<Id extends string> = `effect/unstable/cli/GlobalFlag/${Id}`
|
|
58
66
|
}
|
|
59
67
|
|
|
60
68
|
/**
|
|
@@ -63,7 +71,7 @@ export interface Setting<A> {
|
|
|
63
71
|
* @since 4.0.0
|
|
64
72
|
* @category models
|
|
65
73
|
*/
|
|
66
|
-
export type GlobalFlag<A> = Action<A> | Setting<A>
|
|
74
|
+
export type GlobalFlag<A> = Action<A> | Setting<any, A>
|
|
67
75
|
|
|
68
76
|
/* ========================================================================== */
|
|
69
77
|
/* Constructors */
|
|
@@ -93,21 +101,31 @@ export const action = <A>(options: {
|
|
|
93
101
|
* @since 4.0.0
|
|
94
102
|
* @category constructors
|
|
95
103
|
*/
|
|
96
|
-
export const setting = <
|
|
104
|
+
export const setting = <const Id extends string>(
|
|
105
|
+
id: Id
|
|
106
|
+
) =>
|
|
107
|
+
<A>(options: {
|
|
97
108
|
readonly flag: Flag.Flag<A>
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
109
|
+
}): Setting<Id, A> => {
|
|
110
|
+
settingIdCounter += 1
|
|
111
|
+
const ref = ServiceMap.Service<Setting.Identifier<Id>, A>(
|
|
112
|
+
`effect/unstable/cli/GlobalFlag/${id}/${settingIdCounter}`
|
|
113
|
+
)
|
|
114
|
+
return Object.assign(ref, {
|
|
115
|
+
_tag: "Setting" as const,
|
|
116
|
+
id,
|
|
117
|
+
flag: options.flag
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
let settingIdCounter = 0
|
|
104
122
|
|
|
105
123
|
/* ========================================================================== */
|
|
106
124
|
/* Built-in Flag References */
|
|
107
125
|
/* ========================================================================== */
|
|
108
126
|
|
|
109
127
|
import * as CommandDescriptor from "./internal/completions/CommandDescriptor.ts"
|
|
110
|
-
import * as
|
|
128
|
+
import * as CompletionsInternal from "./internal/completions/Completions.ts"
|
|
111
129
|
import * as HelpInternal from "./internal/help.ts"
|
|
112
130
|
|
|
113
131
|
/**
|
|
@@ -117,24 +135,18 @@ import * as HelpInternal from "./internal/help.ts"
|
|
|
117
135
|
* @since 4.0.0
|
|
118
136
|
* @category references
|
|
119
137
|
*/
|
|
120
|
-
export const Help:
|
|
121
|
-
"
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const helpDoc = yield* HelpInternal.getHelpForCommandPath(command, commandPath, Registry)
|
|
133
|
-
yield* Console.log(formatter.formatHelpDoc(helpDoc))
|
|
134
|
-
})
|
|
135
|
-
})
|
|
136
|
-
}
|
|
137
|
-
)
|
|
138
|
+
export const Help: Action<boolean> = action({
|
|
139
|
+
flag: Flag.boolean("help").pipe(
|
|
140
|
+
Flag.withAlias("h"),
|
|
141
|
+
Flag.withDescription("Show help information")
|
|
142
|
+
),
|
|
143
|
+
run: (_, { command, commandPath }) =>
|
|
144
|
+
Effect.gen(function*() {
|
|
145
|
+
const formatter = yield* CliOutput.Formatter
|
|
146
|
+
const helpDoc = yield* HelpInternal.getHelpForCommandPath(command, commandPath, BuiltIns)
|
|
147
|
+
yield* Console.log(formatter.formatHelpDoc(helpDoc))
|
|
148
|
+
})
|
|
149
|
+
})
|
|
138
150
|
|
|
139
151
|
/**
|
|
140
152
|
* The `--version` global flag.
|
|
@@ -143,22 +155,16 @@ export const Help: ServiceMap.Reference<Action<boolean>> = ServiceMap.Reference(
|
|
|
143
155
|
* @since 4.0.0
|
|
144
156
|
* @category references
|
|
145
157
|
*/
|
|
146
|
-
export const Version:
|
|
147
|
-
"
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const formatter = yield* CliOutput.Formatter
|
|
157
|
-
yield* Console.log(formatter.formatVersion(command.name, version))
|
|
158
|
-
})
|
|
159
|
-
})
|
|
160
|
-
}
|
|
161
|
-
)
|
|
158
|
+
export const Version: Action<boolean> = action({
|
|
159
|
+
flag: Flag.boolean("version").pipe(
|
|
160
|
+
Flag.withDescription("Show version information")
|
|
161
|
+
),
|
|
162
|
+
run: (_, { command, version }) =>
|
|
163
|
+
Effect.gen(function*() {
|
|
164
|
+
const formatter = yield* CliOutput.Formatter
|
|
165
|
+
yield* Console.log(formatter.formatVersion(command.name, version))
|
|
166
|
+
})
|
|
167
|
+
})
|
|
162
168
|
|
|
163
169
|
/**
|
|
164
170
|
* The `--completions` global flag.
|
|
@@ -167,25 +173,20 @@ export const Version: ServiceMap.Reference<Action<boolean>> = ServiceMap.Referen
|
|
|
167
173
|
* @since 4.0.0
|
|
168
174
|
* @category references
|
|
169
175
|
*/
|
|
170
|
-
export const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const descriptor = CommandDescriptor.fromCommand(command)
|
|
185
|
-
yield* Console.log(
|
|
186
|
-
Completions.generate(command.name, shell.value, descriptor)
|
|
187
|
-
)
|
|
188
|
-
})
|
|
176
|
+
export const Completions: Action<Option.Option<"bash" | "zsh" | "fish">> = action({
|
|
177
|
+
flag: Flag.choice("completions", ["bash", "zsh", "fish", "sh"] as const)
|
|
178
|
+
.pipe(
|
|
179
|
+
Flag.optional,
|
|
180
|
+
Flag.map((v) => Option.map(v, (s) => s === "sh" ? "bash" : s)),
|
|
181
|
+
Flag.withDescription("Print shell completion script")
|
|
182
|
+
),
|
|
183
|
+
run: (shell, { command }) =>
|
|
184
|
+
Effect.gen(function*() {
|
|
185
|
+
if (Option.isNone(shell)) return
|
|
186
|
+
const descriptor = CommandDescriptor.fromCommand(command)
|
|
187
|
+
yield* Console.log(
|
|
188
|
+
CompletionsInternal.generate(command.name, shell.value, descriptor)
|
|
189
|
+
)
|
|
189
190
|
})
|
|
190
191
|
})
|
|
191
192
|
|
|
@@ -196,147 +197,47 @@ export const CompletionsFlag: ServiceMap.Reference<
|
|
|
196
197
|
* @since 4.0.0
|
|
197
198
|
* @category references
|
|
198
199
|
*/
|
|
199
|
-
export const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
).pipe(
|
|
218
|
-
Flag.optional,
|
|
219
|
-
Flag.withDescription("Sets the minimum log level")
|
|
220
|
-
),
|
|
221
|
-
layer: (value) =>
|
|
222
|
-
Option.match(value, {
|
|
223
|
-
onNone: () => Layer.empty,
|
|
224
|
-
onSome: (level) => Layer.succeed(References.MinimumLogLevel, level)
|
|
225
|
-
})
|
|
226
|
-
})
|
|
200
|
+
export const LogLevel: Setting<"log-level", Option.Option<LogLevelType>> = setting("log-level")({
|
|
201
|
+
flag: Flag.choiceWithValue(
|
|
202
|
+
"log-level",
|
|
203
|
+
[
|
|
204
|
+
["all", "All"],
|
|
205
|
+
["trace", "Trace"],
|
|
206
|
+
["debug", "Debug"],
|
|
207
|
+
["info", "Info"],
|
|
208
|
+
["warn", "Warn"],
|
|
209
|
+
["warning", "Warn"],
|
|
210
|
+
["error", "Error"],
|
|
211
|
+
["fatal", "Fatal"],
|
|
212
|
+
["none", "None"]
|
|
213
|
+
] as const
|
|
214
|
+
).pipe(
|
|
215
|
+
Flag.optional,
|
|
216
|
+
Flag.withDescription("Sets the minimum log level")
|
|
217
|
+
)
|
|
227
218
|
})
|
|
228
219
|
|
|
229
220
|
/* ========================================================================== */
|
|
230
|
-
/*
|
|
221
|
+
/* References */
|
|
231
222
|
/* ========================================================================== */
|
|
232
223
|
|
|
233
224
|
/**
|
|
234
|
-
*
|
|
235
|
-
* The parser iterates this set to know which flags to extract.
|
|
225
|
+
* Built-in global flags in default precedence order.
|
|
236
226
|
*
|
|
237
227
|
* @since 4.0.0
|
|
238
228
|
* @category references
|
|
239
229
|
*/
|
|
240
|
-
export const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
Version as ServiceMap.Reference<GlobalFlag<any>>,
|
|
247
|
-
CompletionsFlag as ServiceMap.Reference<GlobalFlag<any>>,
|
|
248
|
-
LogLevelFlag as ServiceMap.Reference<GlobalFlag<any>>
|
|
249
|
-
])
|
|
250
|
-
})
|
|
251
|
-
|
|
252
|
-
/* ========================================================================== */
|
|
253
|
-
/* Public API */
|
|
254
|
-
/* ========================================================================== */
|
|
230
|
+
export const BuiltIns: ReadonlyArray<GlobalFlag<any>> = [
|
|
231
|
+
Help,
|
|
232
|
+
Version,
|
|
233
|
+
Completions,
|
|
234
|
+
LogLevel
|
|
235
|
+
]
|
|
255
236
|
|
|
256
237
|
/**
|
|
257
|
-
*
|
|
238
|
+
* Built-in setting context identifiers.
|
|
258
239
|
*
|
|
259
240
|
* @since 4.0.0
|
|
260
|
-
* @category
|
|
261
|
-
*/
|
|
262
|
-
export const add: {
|
|
263
|
-
/* ========================================================================== */
|
|
264
|
-
/* Public API */
|
|
265
|
-
/* ========================================================================== */
|
|
266
|
-
|
|
267
|
-
/**
|
|
268
|
-
* Adds a global flag to the registry.
|
|
269
|
-
*
|
|
270
|
-
* @since 4.0.0
|
|
271
|
-
* @category modifiers
|
|
272
|
-
*/
|
|
273
|
-
<A>(ref: ServiceMap.Reference<GlobalFlag<A>>): <B, E, R>(
|
|
274
|
-
self: Effect.Effect<B, E, R>
|
|
275
|
-
) => Effect.Effect<B, E, R>
|
|
276
|
-
/* ========================================================================== */
|
|
277
|
-
/* Public API */
|
|
278
|
-
/* ========================================================================== */
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
* Adds a global flag to the registry.
|
|
282
|
-
*
|
|
283
|
-
* @since 4.0.0
|
|
284
|
-
* @category modifiers
|
|
285
|
-
*/
|
|
286
|
-
<B, E, R, A>(self: Effect.Effect<B, E, R>, ref: ServiceMap.Reference<GlobalFlag<A>>): Effect.Effect<B, E, R>
|
|
287
|
-
} = dual(
|
|
288
|
-
2,
|
|
289
|
-
Effect.fnUntraced(function*<B, E, R, A>(
|
|
290
|
-
self: Effect.Effect<B, E, R>,
|
|
291
|
-
ref: ServiceMap.Reference<GlobalFlag<A>>
|
|
292
|
-
) {
|
|
293
|
-
const currentRegistry = yield* Registry
|
|
294
|
-
const nextRegistry = new Set([...currentRegistry, ref])
|
|
295
|
-
return yield* Effect.provideService(self, Registry, nextRegistry)
|
|
296
|
-
})
|
|
297
|
-
)
|
|
298
|
-
|
|
299
|
-
/**
|
|
300
|
-
* Removes a global flag by its reference.
|
|
301
|
-
*
|
|
302
|
-
* @since 4.0.0
|
|
303
|
-
* @category modifiers
|
|
304
|
-
*/
|
|
305
|
-
export const remove: {
|
|
306
|
-
/**
|
|
307
|
-
* Removes a global flag by its reference.
|
|
308
|
-
*
|
|
309
|
-
* @since 4.0.0
|
|
310
|
-
* @category modifiers
|
|
311
|
-
*/
|
|
312
|
-
<A>(ref: ServiceMap.Reference<GlobalFlag<A>>): <B, E, R>(
|
|
313
|
-
self: Effect.Effect<B, E, R>
|
|
314
|
-
) => Effect.Effect<B, E, R>
|
|
315
|
-
/**
|
|
316
|
-
* Removes a global flag by its reference.
|
|
317
|
-
*
|
|
318
|
-
* @since 4.0.0
|
|
319
|
-
* @category modifiers
|
|
320
|
-
*/
|
|
321
|
-
<B, E, R, A>(self: Effect.Effect<B, E, R>, ref: ServiceMap.Reference<GlobalFlag<A>>): Effect.Effect<B, E, R>
|
|
322
|
-
} = dual(
|
|
323
|
-
2,
|
|
324
|
-
Effect.fnUntraced(function*<B, E, R, A>(
|
|
325
|
-
self: Effect.Effect<B, E, R>,
|
|
326
|
-
ref: ServiceMap.Reference<GlobalFlag<A>>
|
|
327
|
-
) {
|
|
328
|
-
const currentRegistry = yield* Registry
|
|
329
|
-
const nextRegistry = new Set(currentRegistry)
|
|
330
|
-
nextRegistry.delete(ref)
|
|
331
|
-
return yield* Effect.provideService(self, Registry, nextRegistry)
|
|
332
|
-
})
|
|
333
|
-
)
|
|
334
|
-
|
|
335
|
-
/**
|
|
336
|
-
* Removes all global flags (built-in and user-defined).
|
|
337
|
-
*
|
|
338
|
-
* @since 4.0.0
|
|
339
|
-
* @category modifiers
|
|
241
|
+
* @category models
|
|
340
242
|
*/
|
|
341
|
-
export
|
|
342
|
-
Effect.provideService(self, Registry, new Set())
|
|
243
|
+
export type BuiltInSettingContext = Setting.Identifier<"log-level">
|
|
@@ -12,6 +12,7 @@ import { pipeArguments } from "../../../Pipeable.ts"
|
|
|
12
12
|
import * as Predicate from "../../../Predicate.ts"
|
|
13
13
|
import * as ServiceMap from "../../../ServiceMap.ts"
|
|
14
14
|
import * as CliError from "../CliError.ts"
|
|
15
|
+
import type * as GlobalFlag from "../GlobalFlag.ts"
|
|
15
16
|
import type { ArgDoc, ExampleDoc, FlagDoc, HelpDoc, SubcommandGroupDoc } from "../HelpDoc.ts"
|
|
16
17
|
import * as Param from "../Param.ts"
|
|
17
18
|
import * as Primitive from "../Primitive.ts"
|
|
@@ -36,6 +37,7 @@ export interface CommandInternal<Name extends string, Input, E, R> extends Comma
|
|
|
36
37
|
readonly config: ConfigInternal
|
|
37
38
|
readonly service: ServiceMap.Service<CommandContext<Name>, Input>
|
|
38
39
|
readonly annotations: ServiceMap.ServiceMap<never>
|
|
40
|
+
readonly globalFlags: ReadonlyArray<GlobalFlag.GlobalFlag<any>>
|
|
39
41
|
readonly parse: (input: ParsedTokens) => Effect.Effect<Input, CliError.CliError, Environment>
|
|
40
42
|
readonly handle: (
|
|
41
43
|
input: Input,
|
|
@@ -88,6 +90,7 @@ export const makeCommand = <const Name extends string, Input, E, R>(options: {
|
|
|
88
90
|
readonly config: ConfigInternal
|
|
89
91
|
readonly service?: ServiceMap.Service<CommandContext<Name>, Input> | undefined
|
|
90
92
|
readonly annotations?: ServiceMap.ServiceMap<never> | undefined
|
|
93
|
+
readonly globalFlags?: ReadonlyArray<GlobalFlag.GlobalFlag<any>> | undefined
|
|
91
94
|
readonly description?: string | undefined
|
|
92
95
|
readonly shortDescription?: string | undefined
|
|
93
96
|
readonly alias?: string | undefined
|
|
@@ -101,6 +104,7 @@ export const makeCommand = <const Name extends string, Input, E, R>(options: {
|
|
|
101
104
|
const service = options.service ?? ServiceMap.Service<CommandContext<Name>, Input>(`${TypeId}/${options.name}`)
|
|
102
105
|
const config = options.config
|
|
103
106
|
const annotations = options.annotations ?? ServiceMap.empty()
|
|
107
|
+
const globalFlags = options.globalFlags ?? []
|
|
104
108
|
const subcommands = options.subcommands ?? []
|
|
105
109
|
|
|
106
110
|
const handle = (
|
|
@@ -191,6 +195,7 @@ export const makeCommand = <const Name extends string, Input, E, R>(options: {
|
|
|
191
195
|
name: options.name,
|
|
192
196
|
examples: options.examples ?? [],
|
|
193
197
|
annotations,
|
|
198
|
+
globalFlags,
|
|
194
199
|
subcommands,
|
|
195
200
|
config,
|
|
196
201
|
service,
|
|
@@ -6,49 +6,129 @@
|
|
|
6
6
|
* Extracted from command.ts to avoid circular dependencies.
|
|
7
7
|
*/
|
|
8
8
|
import * as Effect from "../../../Effect.ts"
|
|
9
|
-
import type * as ServiceMap from "../../../ServiceMap.ts"
|
|
10
9
|
import type { Command } from "../Command.ts"
|
|
11
|
-
import type
|
|
10
|
+
import type * as GlobalFlag from "../GlobalFlag.ts"
|
|
12
11
|
import type { FlagDoc, HelpDoc } from "../HelpDoc.ts"
|
|
13
12
|
import * as Param from "../Param.ts"
|
|
14
13
|
import * as Primitive from "../Primitive.ts"
|
|
15
14
|
import { toImpl } from "./command.ts"
|
|
16
15
|
|
|
16
|
+
const dedupeGlobalFlags = (
|
|
17
|
+
flags: ReadonlyArray<GlobalFlag.GlobalFlag<any>>
|
|
18
|
+
): ReadonlyArray<GlobalFlag.GlobalFlag<any>> => {
|
|
19
|
+
const seen = new Set<GlobalFlag.GlobalFlag<any>>()
|
|
20
|
+
const deduped: Array<GlobalFlag.GlobalFlag<any>> = []
|
|
21
|
+
for (const flag of flags) {
|
|
22
|
+
if (seen.has(flag)) {
|
|
23
|
+
continue
|
|
24
|
+
}
|
|
25
|
+
seen.add(flag)
|
|
26
|
+
deduped.push(flag)
|
|
27
|
+
}
|
|
28
|
+
return deduped
|
|
29
|
+
}
|
|
30
|
+
|
|
17
31
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* Reads global flags from the registry and includes them in the help doc.
|
|
32
|
+
* Returns the resolved command lineage for the provided path.
|
|
33
|
+
* Includes the root command as the first element.
|
|
21
34
|
*/
|
|
22
|
-
export const
|
|
35
|
+
export const getCommandsForCommandPath = <Name extends string, Input, E, R>(
|
|
23
36
|
command: Command<Name, Input, E, R>,
|
|
24
|
-
commandPath: ReadonlyArray<string
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
let currentCommand: Command.Any = command
|
|
37
|
+
commandPath: ReadonlyArray<string>
|
|
38
|
+
): ReadonlyArray<Command.Any> => {
|
|
39
|
+
const commands: Array<Command.Any> = [command]
|
|
40
|
+
let currentCommand: Command.Any = command
|
|
29
41
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
42
|
+
for (let i = 1; i < commandPath.length; i++) {
|
|
43
|
+
const subcommandName = commandPath[i]
|
|
44
|
+
let subcommand: Command.Any | undefined = undefined
|
|
33
45
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
46
|
+
for (const group of currentCommand.subcommands) {
|
|
47
|
+
subcommand = group.commands.find((sub) => sub.name === subcommandName)
|
|
48
|
+
if (subcommand) {
|
|
49
|
+
break
|
|
39
50
|
}
|
|
51
|
+
}
|
|
40
52
|
|
|
41
|
-
|
|
42
|
-
|
|
53
|
+
if (!subcommand) {
|
|
54
|
+
break
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
commands.push(subcommand)
|
|
58
|
+
currentCommand = subcommand
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return commands
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Returns active global flags for a command path.
|
|
66
|
+
* Built-ins are prepended and declarations are collected root -> leaf.
|
|
67
|
+
*/
|
|
68
|
+
export const getGlobalFlagsForCommandPath = <Name extends string, Input, E, R>(
|
|
69
|
+
command: Command<Name, Input, E, R>,
|
|
70
|
+
commandPath: ReadonlyArray<string>,
|
|
71
|
+
builtIns: ReadonlyArray<GlobalFlag.GlobalFlag<any>>
|
|
72
|
+
): ReadonlyArray<GlobalFlag.GlobalFlag<any>> => {
|
|
73
|
+
const commands = getCommandsForCommandPath(command, commandPath)
|
|
74
|
+
const declared = commands.flatMap((current) => toImpl(current).globalFlags)
|
|
75
|
+
return dedupeGlobalFlags([
|
|
76
|
+
...builtIns,
|
|
77
|
+
...declared
|
|
78
|
+
])
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const collectDeclaredGlobalFlags = (command: Command.Any): ReadonlyArray<GlobalFlag.GlobalFlag<any>> => {
|
|
82
|
+
const collected: Array<GlobalFlag.GlobalFlag<any>> = []
|
|
83
|
+
|
|
84
|
+
const visit = (current: Command.Any): void => {
|
|
85
|
+
const impl = toImpl(current)
|
|
86
|
+
for (const flag of impl.globalFlags) {
|
|
87
|
+
collected.push(flag)
|
|
88
|
+
}
|
|
89
|
+
for (const group of current.subcommands) {
|
|
90
|
+
for (const subcommand of group.commands) {
|
|
91
|
+
visit(subcommand)
|
|
43
92
|
}
|
|
44
93
|
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
visit(command)
|
|
97
|
+
return dedupeGlobalFlags(collected)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Returns all global flags declared in a command tree.
|
|
102
|
+
* Built-ins are prepended and command declarations are deduplicated by identity.
|
|
103
|
+
*/
|
|
104
|
+
export const getGlobalFlagsForCommandTree = <Name extends string, Input, E, R>(
|
|
105
|
+
command: Command<Name, Input, E, R>,
|
|
106
|
+
builtIns: ReadonlyArray<GlobalFlag.GlobalFlag<any>>
|
|
107
|
+
): ReadonlyArray<GlobalFlag.GlobalFlag<any>> =>
|
|
108
|
+
dedupeGlobalFlags([
|
|
109
|
+
...builtIns,
|
|
110
|
+
...collectDeclaredGlobalFlags(command)
|
|
111
|
+
])
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Helper function to get help documentation for a specific command path.
|
|
115
|
+
* Navigates through the command hierarchy to find the right command.
|
|
116
|
+
* Reads active global flags for the path and includes them in the help doc.
|
|
117
|
+
*/
|
|
118
|
+
export const getHelpForCommandPath = <Name extends string, Input, E, R>(
|
|
119
|
+
command: Command<Name, Input, E, R>,
|
|
120
|
+
commandPath: ReadonlyArray<string>,
|
|
121
|
+
builtIns: ReadonlyArray<GlobalFlag.GlobalFlag<any>>
|
|
122
|
+
): Effect.Effect<HelpDoc, never, never> =>
|
|
123
|
+
Effect.gen(function*() {
|
|
124
|
+
const commands = getCommandsForCommandPath(command, commandPath)
|
|
125
|
+
const currentCommand = commands.length > 0 ? commands[commands.length - 1] : command
|
|
45
126
|
|
|
46
127
|
const baseDoc = toImpl(currentCommand).buildHelpDoc(commandPath)
|
|
47
128
|
|
|
48
|
-
const
|
|
129
|
+
const flags = getGlobalFlagsForCommandPath(command, commandPath, builtIns)
|
|
49
130
|
const globalFlagDocs: Array<FlagDoc> = []
|
|
50
|
-
for (const
|
|
51
|
-
const flag = yield* ref
|
|
131
|
+
for (const flag of flags) {
|
|
52
132
|
const singles = Param.extractSingleParams(flag.flag)
|
|
53
133
|
for (const single of singles) {
|
|
54
134
|
const formattedAliases = single.aliases.map((alias) => alias.length === 1 ? `-${alias}` : `--${alias}`)
|