1/**
2 * Glob pattern matching service.
3 *
4 * @since 4.0.0
5 */
6import * as Context from "effect/Context"
7import * as Data from "effect/Data"
8import * as Effect from "effect/Effect"
9import * as Layer from "effect/Layer"
10import * as GlobLib from "glob"
11
12/**
13 * Error during glob pattern matching.
14 *
15 * @category errors
16 * @since 4.0.0
17 */
18export class GlobError extends Data.TaggedError("GlobError")<{
19 readonly pattern: string | ReadonlyArray<string>
20 readonly cause: unknown
21}> {}
22
23/**
24 * Service for glob pattern matching.
25 *
26 * @category services
27 * @since 4.0.0
28 */
29export interface Glob {
30 readonly glob: (
31 pattern: string | ReadonlyArray<string>,
32 options?: GlobLib.GlobOptions
33 ) => Effect.Effect<Array<string>, GlobError>
34}
35
36/**
37 * Service tag for glob pattern matching used by AI codegen tooling.
38 *
39 * @category services
40 * @since 4.0.0
41 */
42export const Glob: Context.Service<Glob, Glob> = Context.Service("@effect/ai-codegen/Glob")
43
44/**
45 * Layer providing the Glob service.
46 *
47 * @category layers
48 * @since 4.0.0
49 */
50export const layer: Layer.Layer<Glob> = Layer.succeed(Glob, {
51 glob: (pattern, options) =>
52 Effect.tryPromise({
53 try: () => GlobLib.glob(pattern as string | Array<string>, options ?? {}) as Promise<Array<string>>,
54 catch: (cause) => new GlobError({ pattern, cause })
55 })
56})