( viewsDir: string, views: IntrospectionViewDefinition[], )
| 40 | } |
| 41 | |
| 42 | async function createViewsIO( |
| 43 | viewsDir: string, |
| 44 | views: IntrospectionViewDefinition[], |
| 45 | ): Promise<{ viewFilesToKeep: string[] }> { |
| 46 | // collect the newest view definitions |
| 47 | const viewEntries = views.map(({ schema, ...rest }) => { |
| 48 | const viewDir = path.posix.join(viewsDir, schema) |
| 49 | return [viewDir, rest] as const |
| 50 | }) |
| 51 | |
| 52 | // collect the paths to the view directories (identified by their db schema name) corresponding to the newest view definitions, |
| 53 | // which will be created later if they don't exist |
| 54 | const viewPathsToWrite: string[] = viewEntries.map(([viewDir]) => viewDir) |
| 55 | |
| 56 | // collect the files paths and content for the newest views' SQL definitions, which will be created later if they don't exist |
| 57 | const viewsFilesToWrite = viewEntries.map(([viewDir, { name, definition }]) => { |
| 58 | const viewFile = path.posix.join(viewDir, `${name}.sql`) |
| 59 | return { path: viewFile, content: definition } as const |
| 60 | }) |
| 61 | |
| 62 | const viewFilesToKeep = viewsFilesToWrite.map(({ path }) => path) |
| 63 | |
| 64 | const pipeline = pipe( |
| 65 | // create the views directory, idempotently |
| 66 | fsFunctional.createDirIfNotExists(viewsDir), |
| 67 | |
| 68 | // create the view directories, idempotently and concurrently, collapsing the possible errors |
| 69 | TE.chainW(() => TE.traverseArray(fsFunctional.createDirIfNotExists)(viewPathsToWrite)), |
| 70 | |
| 71 | // write the view definitions in the directories just created, idempotently and concurrently, collapsing the possible errors |
| 72 | TE.chainW(() => TE.traverseArray(fsFunctional.writeFile)(viewsFilesToWrite)), |
| 73 | ) |
| 74 | |
| 75 | const either = await pipeline() |
| 76 | |
| 77 | if (E.isRight(either)) { |
| 78 | return { viewFilesToKeep } |
| 79 | } |
| 80 | |
| 81 | // failure: check which error to throw |
| 82 | const error = match(either.left) |
| 83 | .with({ type: 'fs-create-dir' }, (e) => { |
| 84 | throw new Error(`Error creating the directory: ${e.meta.dir}.\n${e.error}.`) |
| 85 | }) |
| 86 | .with({ type: 'fs-write-file' }, (e) => { |
| 87 | throw new Error(`Error writing the view definition\n${e.meta.content}\nto file ${e.meta.path}.\n${e.error}.`) |
| 88 | }) |
| 89 | .exhaustive() |
| 90 | |
| 91 | throw error |
| 92 | } |
| 93 | |
| 94 | /** |
| 95 | * - Delete every *.sql file in the subfolders of viewsDir |
no test coverage detected