Skip to content

Commit 65eabb0

Browse files
Simplify file loader
1 parent 990c15a commit 65eabb0

1 file changed

Lines changed: 44 additions & 107 deletions

File tree

Lines changed: 44 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,110 +1,38 @@
11
import fs from 'fs/promises'
2-
import crypto from 'node:crypto'
3-
import path from 'node:path'
42

5-
import Boom from '@hapi/boom'
63
import YAML from 'yaml'
74

85
/**
9-
* Create a deterministic UUID string
10-
* @param {string} seed - the seed string
11-
* @returns string
12-
*/
13-
function uuid(seed) {
14-
const uuidLen = 36
15-
const firstSepIdx = 8
16-
const secondSepIdx = 13
17-
const thirdSepIdx = 18
18-
const forthSepIdx = 23
19-
const hash = crypto
20-
.createHash('sha256')
21-
.update(seed.toString())
22-
.digest('hex')
23-
.substring(0, uuidLen)
24-
const chars = hash.split('')
25-
26-
chars[firstSepIdx] = '-'
27-
chars[secondSepIdx] = '-'
28-
chars[secondSepIdx + 1] = '4'
29-
chars[thirdSepIdx] = '-'
30-
chars[thirdSepIdx + 1] = '8'
31-
chars[forthSepIdx] = '-'
32-
33-
return chars.join('')
34-
}
35-
36-
/**
37-
* FileFormService
6+
* FileFormService abstract class
387
*/
398
class FileFormService {
409
/**
41-
* @type {string}
42-
*/
43-
#ext
44-
45-
/**
46-
* @type {PartialFormMetadata}
47-
*/
48-
#defaultMetadata
49-
50-
/**
10+
* The map of form metadatas by slug
5111
* @type {Map<string, FormMetadata>}
5212
*/
5313
#metadata = new Map()
5414

5515
/**
16+
* The map of form definitions by id
5617
* @type {Map<string, FormDefinition>}
5718
*/
5819
#definition = new Map()
5920

6021
/**
61-
* @param {string} ext - the file type extension
62-
* @param {PartialFormMetadata} metadata - the default partial form metadata to use for all forms
63-
*/
64-
constructor(ext, metadata) {
65-
this.#ext = ext.toLowerCase()
66-
this.#defaultMetadata = metadata
67-
}
68-
69-
/**
70-
* @param {string} dir
71-
* @param {PartialFormMetadata} metadata - the partial metadata to use for this form
72-
*/
73-
async addDir(dir, metadata = this.#defaultMetadata) {
74-
const dirents = await fs.readdir(dir, { withFileTypes: true })
75-
const fileEntries = dirents.filter(
76-
(entry) =>
77-
entry.isFile() &&
78-
path.extname(entry.name).toLowerCase() === `.${this.#ext}`
79-
)
80-
81-
// Read each file
82-
for (const entry of fileEntries) {
83-
await this.addForm(
84-
`${entry.parentPath}${path.sep}${entry.name}`,
85-
metadata
86-
)
87-
}
88-
}
89-
90-
/**
91-
* @param {string} filepath
92-
* @param {PartialFormMetadata} metadata - the metadata to use for this form
22+
* Add form from a file
23+
* @param {string} filepath - the file path
24+
* @param {FormMetadata} metadata - the metadata to use for this form
9325
*/
94-
async addForm(filepath, metadata = this.#defaultMetadata) {
26+
async addForm(filepath, metadata) {
9527
const definition = await this.readFormDefintion(filepath)
96-
const filename = path.basename(filepath)
97-
const slug = path.basename(filename, `.${this.#ext}`)
98-
const id = uuid(filename)
99-
const title = definition.name ?? slug
100-
const fullMetadata = { ...metadata, id, slug, title }
101-
102-
this.#metadata.set(slug, fullMetadata)
103-
this.#definition.set(id, definition)
28+
29+
this.#metadata.set(metadata.slug, metadata)
30+
this.#definition.set(metadata.id, definition)
10431
}
10532

10633
/**
107-
* @param {string} filepath
34+
* Read the form definition from file
35+
* @param {string} filepath - the file path
10836
* @returns {Promise<FormDefinition>}
10937
*/
11038
// eslint-disable-next-line @typescript-eslint/require-await
@@ -116,33 +44,59 @@ class FileFormService {
11644

11745
/**
11846
* Get the form metadata by slug
119-
* @param {string} slug
47+
* @param {string} slug - the form slug
12048
* @returns {FormMetadata}
12149
*/
12250
getFormMetadata(slug) {
12351
const metadata = this.#metadata.get(slug)
12452

12553
if (!metadata) {
126-
throw Boom.notFound(`Form '${slug}' not found`)
54+
throw new Error(`Form metadata '${slug}' not found`)
12755
}
12856

12957
return metadata
13058
}
13159

13260
/**
13361
* Get the form defintion by id
134-
* @param {string} id
62+
* @param {string} id - the form id
13563
* @returns {FormDefinition}
13664
*/
13765
getFormDefinition(id) {
13866
const definition = this.#definition.get(id)
13967

14068
if (!definition) {
141-
throw Boom.notFound(`Form '${id}' not found`)
69+
throw new Error(`Form definition '${id}' not found`)
14270
}
14371

14472
return definition
14573
}
74+
75+
/**
76+
* Returns a FormsService compliant interface
77+
* @returns {import('~/src/server/types.js').FormsService}
78+
*/
79+
toFormService() {
80+
return {
81+
/**
82+
* Get the form metadata by slug
83+
* @param {string} slug
84+
* @returns {Promise<FormMetadata>}
85+
*/
86+
getFormMetadata: (slug) => {
87+
return Promise.resolve(this.getFormMetadata(slug))
88+
},
89+
90+
/**
91+
* Get the form defintion by id
92+
* @param {string} id
93+
* @returns {Promise<FormDefinition>}
94+
*/
95+
getFormDefinition: (id) => {
96+
return Promise.resolve(this.getFormDefinition(id))
97+
}
98+
}
99+
}
146100
}
147101

148102
/**
@@ -151,13 +105,7 @@ class FileFormService {
151105
*/
152106
export class JsonFileFormService extends FileFormService {
153107
/**
154-
* @param {FormMetadata} metadata - the default metadata to use for all forms
155-
*/
156-
constructor(metadata) {
157-
super('json', metadata)
158-
}
159-
160-
/**
108+
* Read the form definition from a json file
161109
* @param {string} filepath
162110
* @returns {Promise<FormDefinition>}
163111
*/
@@ -178,13 +126,7 @@ export class JsonFileFormService extends FileFormService {
178126
*/
179127
export class YamlFileFormService extends FileFormService {
180128
/**
181-
* @param {FormMetadata} metadata - the default metadata to use for all forms
182-
*/
183-
constructor(metadata) {
184-
super('yaml', metadata)
185-
}
186-
187-
/**
129+
* Read the form definition from a yaml file
188130
* @param {string} filepath
189131
* @returns {Promise<FormDefinition>}
190132
*/
@@ -202,8 +144,3 @@ export class YamlFileFormService extends FileFormService {
202144
/**
203145
* @import { FormMetadata, FormDefinition } from '@defra/forms-model'
204146
*/
205-
206-
/**
207-
* Partial FormMetadata
208-
* @typedef {Omit<FormMetadata, "id" | "slug" | "title">} PartialFormMetadata
209-
*/

0 commit comments

Comments
 (0)