@forgehive/record-tape 0.0.1

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.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/dist/index.d.ts +51 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +176 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/tests/compile-cache.test.d.ts +2 -0
  7. package/dist/tests/compile-cache.test.d.ts.map +1 -0
  8. package/dist/tests/compile-cache.test.js +34 -0
  9. package/dist/tests/compile-cache.test.js.map +1 -0
  10. package/dist/tests/index.test.d.ts +2 -0
  11. package/dist/tests/index.test.d.ts.map +1 -0
  12. package/dist/tests/index.test.js +99 -0
  13. package/dist/tests/index.test.js.map +1 -0
  14. package/dist/tests/load.test.d.ts +2 -0
  15. package/dist/tests/load.test.d.ts.map +1 -0
  16. package/dist/tests/load.test.js +89 -0
  17. package/dist/tests/load.test.js.map +1 -0
  18. package/dist/tests/log-format.test.d.ts +2 -0
  19. package/dist/tests/log-format.test.d.ts.map +1 -0
  20. package/dist/tests/log-format.test.js +36 -0
  21. package/dist/tests/log-format.test.js.map +1 -0
  22. package/dist/tests/mode.test.d.ts +2 -0
  23. package/dist/tests/mode.test.d.ts.map +1 -0
  24. package/dist/tests/mode.test.js +75 -0
  25. package/dist/tests/mode.test.js.map +1 -0
  26. package/dist/tests/save.test.d.ts +2 -0
  27. package/dist/tests/save.test.d.ts.map +1 -0
  28. package/dist/tests/save.test.js +95 -0
  29. package/dist/tests/save.test.js.map +1 -0
  30. package/dist/tests/task-listener.test.d.ts +2 -0
  31. package/dist/tests/task-listener.test.d.ts.map +1 -0
  32. package/dist/tests/task-listener.test.js +122 -0
  33. package/dist/tests/task-listener.test.js.map +1 -0
  34. package/jest.config.js +6 -0
  35. package/package.json +23 -0
  36. package/src/index.ts +218 -0
  37. package/src/tests/compile-cache.test.ts +41 -0
  38. package/src/tests/fixtures/load.log +2 -0
  39. package/src/tests/fixtures/single-cache.log +2 -0
  40. package/src/tests/index.test.ts +88 -0
  41. package/src/tests/load.test.ts +108 -0
  42. package/src/tests/log-format.test.ts +48 -0
  43. package/src/tests/mode.test.ts +93 -0
  44. package/src/tests/save.test.ts +127 -0
  45. package/src/tests/task-listener.test.ts +170 -0
  46. package/tsconfig.json +19 -0
@@ -0,0 +1,88 @@
1
+ import * as path from 'path'
2
+ import { RecordTape } from '../index'
3
+
4
+ const emptyPath = path.resolve('any')
5
+ const tapePath = path.resolve(__dirname, './fixtures/load')
6
+
7
+ describe('Base tests', () => {
8
+ it('Load sync with no file should return a empty tape', () => {
9
+ const tape = new RecordTape({ path: emptyPath })
10
+ tape.loadSync()
11
+
12
+ const data = tape.getLog()
13
+ expect(data.length).toBe(0)
14
+ })
15
+
16
+ it('Load sync with fixture tape should return a tape with one element', () => {
17
+ const tape = new RecordTape({ path: tapePath })
18
+ tape.loadSync()
19
+
20
+ const data = tape.getLog()
21
+ expect(data.length).toBe(2)
22
+ })
23
+
24
+ it('Load with no file should return a empty tape', async () => {
25
+ const tape = new RecordTape({ path: emptyPath })
26
+ await tape.load()
27
+
28
+ const data = tape.getLog()
29
+ expect(data.length).toBe(0)
30
+ })
31
+
32
+ it('Load with fixture tape should return a tape with one element', async () => {
33
+ type InputType = boolean[]
34
+ type OutputType = boolean
35
+
36
+ const tape = new RecordTape<InputType, OutputType>({ path: tapePath })
37
+ await tape.load()
38
+
39
+ const data = tape.getLog()
40
+ expect(data.length).toBe(2)
41
+
42
+ const successRecord = data[0]
43
+ expect(successRecord.type).toBe('success')
44
+ expect(successRecord.input).toEqual([true])
45
+ expect(successRecord.output).toBe(true)
46
+ expect(successRecord.error).toBeUndefined()
47
+
48
+ const errorRecord = data[1]
49
+ expect(errorRecord.type).toBe('error')
50
+ expect(errorRecord.input).toEqual([true])
51
+ expect(errorRecord.output).toBeUndefined()
52
+ expect(errorRecord.error).toBe('invalid data')
53
+ })
54
+
55
+ it('Should create a new tape with generic types', () => {
56
+ type InputType = [{ name: string }]
57
+ type OutputType = {
58
+ age: number
59
+ }
60
+
61
+ const tape = new RecordTape<InputType, OutputType>({ path: emptyPath })
62
+ tape.addLogItem('test', { input: [{name: 'test'}], output: { age: 1 } })
63
+ tape.addLogItem('test', { input: [{name: 'test'}], error: new Error('test') })
64
+
65
+ const data = tape.getLog()
66
+ expect(data.length).toBe(2)
67
+
68
+ const input = data[0].input
69
+ const output = data[0].output
70
+ const type = data[0].type
71
+ const error = data[0].error
72
+
73
+ expect(input).toEqual([{name: 'test'}])
74
+ expect(output).toEqual({ age: 1 })
75
+ expect(error).toBeUndefined()
76
+ expect(type).toBe('success')
77
+
78
+ const input2 = data[1].input
79
+ const output2 = data[1].output
80
+ const type2 = data[1].type
81
+ const error2 = data[1].error
82
+
83
+ expect(input2).toEqual([{name: 'test'}])
84
+ expect(output2).toBeUndefined()
85
+ expect(error2).toEqual(new Error('test'))
86
+ expect(type2).toBe('error')
87
+ })
88
+ })
@@ -0,0 +1,108 @@
1
+ import path from 'path'
2
+ import fs from 'fs'
3
+ import { RecordTape } from '../index'
4
+
5
+ const baseTapeData = [
6
+ {
7
+ name: 'name',
8
+ type: 'success',
9
+ input: [true],
10
+ output: true,
11
+ boundaries: {}
12
+ },
13
+ {
14
+ name: 'name',
15
+ type: 'error',
16
+ input: [true],
17
+ error: 'invalid data',
18
+ boundaries: {}
19
+ }
20
+ ]
21
+
22
+ describe('Load async', () => {
23
+ it('Load async from file', async () => {
24
+ type InputType = boolean[]
25
+ type OutputType = boolean
26
+
27
+ const tape = new RecordTape<InputType, OutputType>({
28
+ path: path.resolve(__dirname, './fixtures/load')
29
+ })
30
+
31
+ await tape.load()
32
+ const log = tape.getLog()
33
+
34
+ expect(log).toEqual(baseTapeData)
35
+ })
36
+
37
+ it('Load async from file on a directory that doesnt exist', async () => {
38
+ const tape = new RecordTape({
39
+ path: path.resolve(__dirname, './nowhere/nop')
40
+ })
41
+
42
+ await expect(tape.load()).rejects.toThrow('Logs folder doesn\'t exists')
43
+ })
44
+
45
+ it('Load async from file that doesnt exist', async () => {
46
+ const tapeFilePath = path.resolve(__dirname, './fixtures/nop')
47
+
48
+ try {
49
+ await fs.promises.unlink(tapeFilePath + '.log')
50
+ } catch (_e) {
51
+ // eslint-disable-next-line no-console
52
+ // console.warn('Didnt found a file to unlink')
53
+ }
54
+
55
+ const tape = new RecordTape({
56
+ path: path.resolve(__dirname, './fixtures/nop')
57
+ })
58
+
59
+ await tape.load()
60
+ const log = tape.getLog()
61
+
62
+ expect(log).toEqual([])
63
+ })
64
+ })
65
+
66
+ describe('Load sync', () => {
67
+ it('load sync from file', () => {
68
+ type InputType = boolean[]
69
+ type OutputType = boolean
70
+
71
+ const tape = new RecordTape<InputType, OutputType>({
72
+ path: path.resolve(__dirname, './fixtures/load')
73
+ })
74
+
75
+ tape.loadSync()
76
+ const log = tape.getLog()
77
+
78
+ expect(log).toEqual(baseTapeData)
79
+ })
80
+
81
+ it('Load sync from file on a directory that doesnt exist', () => {
82
+ const tape = new RecordTape({
83
+ path: path.resolve(__dirname, './somewhere/nop')
84
+ })
85
+
86
+ expect(() => tape.loadSync()).toThrow('Logs folder doesn\'t exists')
87
+ })
88
+
89
+ it('Load sync from file that doesnt exist', () => {
90
+ const tapeFilePath = path.resolve(__dirname, './fixtures/nop')
91
+
92
+ try {
93
+ fs.unlinkSync(tapeFilePath + '.log')
94
+ } catch (_e) {
95
+ // eslint-disable-next-line no-console
96
+ // console.warn('Didnt found a file to unlink')
97
+ }
98
+
99
+ const tape = new RecordTape({
100
+ path: path.resolve(__dirname, './fixtures/nop')
101
+ })
102
+
103
+ tape.loadSync()
104
+ const log = tape.getLog()
105
+
106
+ expect(log).toEqual([])
107
+ })
108
+ })
@@ -0,0 +1,48 @@
1
+ import { RecordTape } from '../index'
2
+
3
+ const baseTapeData = [
4
+ {
5
+ name: 'name',
6
+ type: 'success',
7
+ input: [true],
8
+ output: true,
9
+ boundaries: {}
10
+ },
11
+ {
12
+ name: 'name',
13
+ type: 'error',
14
+ input: [true],
15
+ error: 'invalid data',
16
+ boundaries: {}
17
+ }
18
+ ]
19
+
20
+ const logFileData = '{"name":"name","type":"success","input":[true],"output":true,"boundaries":{}}\n{"name":"name","type":"error","input":[true],"error":"invalid data","boundaries":{}}\n'
21
+
22
+ describe('Log format', () => {
23
+ it('Should ensure format', () => {
24
+ type InputType = boolean[]
25
+ type OutputType = boolean
26
+
27
+ const tape = new RecordTape<InputType, OutputType>({})
28
+
29
+ tape.addLogItem('name', { input: [true], output: true, boundaries: {} })
30
+ tape.addLogItem('name', { input: [true], error: 'invalid data', boundaries: {} })
31
+
32
+ expect(tape.getLog()).toEqual(baseTapeData)
33
+ })
34
+
35
+ it('Should serialize to one line per item', () => {
36
+ type InputType = boolean[]
37
+ type OutputType = boolean
38
+
39
+ const tape = new RecordTape<InputType, OutputType>({})
40
+
41
+ tape.addLogItem('name', { input: [true], output: true, boundaries: {} })
42
+ tape.addLogItem('name', { input: [true], error: 'invalid data', boundaries: {} })
43
+
44
+ const logFile = tape.stringify()
45
+
46
+ expect(logFile).toBe(logFileData)
47
+ })
48
+ })
@@ -0,0 +1,93 @@
1
+ import { RecordTape } from '../index'
2
+
3
+ describe('Mode behavior', () => {
4
+ it('Should start in record mode by default', () => {
5
+ const tape = new RecordTape()
6
+ expect(tape.getMode()).toBe('record')
7
+ })
8
+
9
+ it('Should not add log items in replay mode', () => {
10
+ type InputType = { value: number }
11
+ type OutputType = { result: number }
12
+
13
+ const tape = new RecordTape<InputType, OutputType>()
14
+ tape.setMode('replay')
15
+
16
+ tape.addLogItem('test', {
17
+ input: { value: 1 },
18
+ output: { result: 2 }
19
+ })
20
+
21
+ expect(tape.getLog()).toEqual([])
22
+ })
23
+
24
+ it('Should add log items in record mode', () => {
25
+ type InputType = { value: number }
26
+ type OutputType = { result: number }
27
+
28
+ const tape = new RecordTape<InputType, OutputType>()
29
+ tape.setMode('record')
30
+
31
+ tape.addLogItem('test', {
32
+ input: { value: 1 },
33
+ output: { result: 2 }
34
+ })
35
+
36
+ expect(tape.getLog()).toEqual([
37
+ {
38
+ name: 'test',
39
+ type: 'success',
40
+ input: { value: 1 },
41
+ output: { result: 2 },
42
+ boundaries: {}
43
+ }
44
+ ])
45
+ })
46
+
47
+ it('Should switch between modes', () => {
48
+ type InputType = { value: number }
49
+ type OutputType = { result: number }
50
+
51
+ const tape = new RecordTape<InputType, OutputType>()
52
+
53
+ // Start in record mode
54
+ expect(tape.getMode()).toBe('record')
55
+ tape.addLogItem('test1', {
56
+ input: { value: 1 },
57
+ output: { result: 2 }
58
+ })
59
+
60
+ // Switch to replay mode
61
+ tape.setMode('replay')
62
+ expect(tape.getMode()).toBe('replay')
63
+ tape.addLogItem('test2', {
64
+ input: { value: 3 },
65
+ output: { result: 4 }
66
+ })
67
+
68
+ // Switch back to record mode
69
+ tape.setMode('record')
70
+ expect(tape.getMode()).toBe('record')
71
+ tape.addLogItem('test3', {
72
+ input: { value: 5 },
73
+ output: { result: 6 }
74
+ })
75
+
76
+ expect(tape.getLog()).toEqual([
77
+ {
78
+ name: 'test1',
79
+ type: 'success',
80
+ input: { value: 1 },
81
+ output: { result: 2 },
82
+ boundaries: {}
83
+ },
84
+ {
85
+ name: 'test3',
86
+ type: 'success',
87
+ input: { value: 5 },
88
+ output: { result: 6 },
89
+ boundaries: {}
90
+ }
91
+ ])
92
+ })
93
+ })
@@ -0,0 +1,127 @@
1
+ import fs from 'fs'
2
+ import path from 'path'
3
+ import { RecordTape } from '../index'
4
+
5
+ const logFileData = '{"name":"name","type":"success","input":[true],"output":true,"boundaries":{}}\n{"name":"name","type":"error","input":[true],"error":"invalid data","boundaries":{}}\n'
6
+
7
+ describe('Save to file async', () => {
8
+ it('Save async to existing file(should add new logs)', async () => {
9
+ type InputType = boolean[]
10
+ type OutputType = boolean
11
+
12
+ const tapeFilePath = path.resolve(__dirname, './fixtures/save')
13
+ try {
14
+ await fs.promises.writeFile(tapeFilePath + '.log', logFileData)
15
+ } catch (_e) {
16
+ // eslint-disable-next-line no-console
17
+ // console.warn('Didnt found a file to unlink')
18
+ }
19
+
20
+ const tape = new RecordTape<InputType, OutputType>({ path: tapeFilePath })
21
+ await tape.load()
22
+ tape.addLogItem('name', { input: [true], output: true, boundaries: {} })
23
+ tape.addLogItem('name', { input: [true], error: 'invalid data', boundaries: {} })
24
+ await tape.save()
25
+
26
+ const content = await fs.promises.readFile(tapeFilePath + '.log', 'utf8')
27
+
28
+ expect(tape.getLog().length).toBe(4)
29
+ expect(tape.stringify()).toBe(logFileData + logFileData)
30
+ expect(content).toBe(logFileData + logFileData)
31
+ })
32
+
33
+ it('Save async to a path of invalid folder', async () => {
34
+ type InputType = boolean[]
35
+ type OutputType = boolean
36
+
37
+ const tapeFilePath = path.resolve(__dirname, './nowhere/nop')
38
+
39
+ const tape = new RecordTape<InputType, OutputType>({ path: tapeFilePath })
40
+ tape.addLogItem('name', { input: [true], output: true, boundaries: {} })
41
+ tape.addLogItem('name', { input: [true], error: 'invalid data', boundaries: {} })
42
+
43
+ await expect(tape.save()).rejects.toThrow('Folder doesn\'t exists')
44
+ })
45
+
46
+ it('Save async to a log file that doesnt exist', async () => {
47
+ type InputType = boolean[]
48
+ type OutputType = boolean
49
+
50
+ const tapeFilePath = path.resolve(__dirname, './fixtures/nop')
51
+ try {
52
+ await fs.promises.unlink(tapeFilePath + '.log')
53
+ } catch (_e) {
54
+ // eslint-disable-next-line no-console
55
+ // console.warn('Didnt found a file to unlink')
56
+ }
57
+
58
+ const tape = new RecordTape<InputType, OutputType>({ path: tapeFilePath })
59
+ tape.addLogItem('name', { input: [true], output: true, boundaries: {} })
60
+ tape.addLogItem('name', { input: [true], error: 'invalid data', boundaries: {} })
61
+ await tape.save()
62
+
63
+ const content = await fs.promises.readFile(tapeFilePath + '.log', 'utf8')
64
+
65
+ expect(content).toBe(logFileData)
66
+ })
67
+ })
68
+
69
+ describe('Save to file sync', () => {
70
+ it('Save sync', () => {
71
+ type InputType = boolean[]
72
+ type OutputType = boolean
73
+
74
+ const tapeFilePath = path.resolve(__dirname, './fixtures/save')
75
+ try {
76
+ fs.unlinkSync(tapeFilePath + '.log')
77
+ } catch (_e) {
78
+ // eslint-disable-next-line no-console
79
+ // console.warn('didnt found a file to unlink')
80
+ }
81
+
82
+ const tape = new RecordTape<InputType, OutputType>({ path: tapeFilePath })
83
+ tape.addLogItem('name', { input: [true], output: true, boundaries: {} })
84
+ tape.addLogItem('name', { input: [true], error: 'invalid data', boundaries: {} })
85
+ tape.saveSync()
86
+
87
+ const content = fs.readFileSync(tapeFilePath + '.log', 'utf8')
88
+
89
+ expect(content).toBe(logFileData)
90
+ })
91
+
92
+ it('Save sync to a path of invalid folder', () => {
93
+ type InputType = boolean[]
94
+ type OutputType = boolean
95
+
96
+ const tapeFilePath = path.resolve(__dirname, './nowhere/nop')
97
+
98
+ const tape = new RecordTape<InputType, OutputType>({ path: tapeFilePath })
99
+ tape.addLogItem('name', { input: [true], output: true, boundaries: {} })
100
+ tape.addLogItem('name', { input: [true], error: 'invalid data', boundaries: {} })
101
+
102
+ expect(() => tape.saveSync()).toThrow('Folder doesn\'t exists')
103
+ })
104
+
105
+ it('Save sync to a log file that doesnt exist', () => {
106
+ type InputType = boolean[]
107
+ type OutputType = boolean
108
+
109
+ const tapeFilePath = path.resolve(__dirname, './fixtures/nop')
110
+
111
+ try {
112
+ fs.unlinkSync(tapeFilePath + '.log')
113
+ } catch (_e) {
114
+ // eslint-disable-next-line no-console
115
+ // console.warn('Didnt found a file to unlink')
116
+ }
117
+
118
+ const tape = new RecordTape<InputType, OutputType>({ path: tapeFilePath })
119
+ tape.addLogItem('name', { input: [true], output: true, boundaries: {} })
120
+ tape.addLogItem('name', { input: [true], error: 'invalid data', boundaries: {} })
121
+ tape.saveSync()
122
+
123
+ const content = fs.readFileSync(tapeFilePath + '.log', 'utf8')
124
+
125
+ expect(content).toBe(logFileData)
126
+ })
127
+ })
@@ -0,0 +1,170 @@
1
+ import { Task, createTask, Schema } from '@forgehive/task'
2
+ import { RecordTape, LogItem } from '../index'
3
+
4
+ describe('Task listener', () => {
5
+ it('Should listen to task events', async () => {
6
+ type InputType = Record<string, unknown>
7
+ type OutputType = { value: number, foo: boolean }
8
+
9
+ const tape = new RecordTape<InputType, OutputType>({})
10
+ const task = new Task(
11
+ async (_input: InputType): Promise<OutputType> => {
12
+ return { value: 1, foo: true }
13
+ }
14
+ )
15
+
16
+ task.addListener<InputType, OutputType>((record) => {
17
+ const logItem: LogItem<InputType, OutputType> = record.error
18
+ ? { input: record.input, error: record.error, boundaries: record.boundaries }
19
+ : { input: record.input, output: record.output as OutputType, boundaries: record.boundaries }
20
+
21
+ tape.addLogItem('test', logItem)
22
+ })
23
+
24
+ await task.run({})
25
+
26
+ expect(tape.getLog()).toEqual([
27
+ { name: 'test', type: 'success', input: {}, output: { value: 1, foo: true }, boundaries: {} }
28
+ ])
29
+ })
30
+
31
+ it('Should has errors and sucess items', async () => {
32
+ const task = new Task(
33
+ async (input: { value: number }): Promise<{ result: number }> => {
34
+ if (input.value < 10 || input.value > 20) {
35
+ throw new Error('Value is not between 10 and 20')
36
+ }
37
+
38
+ return { result: input.value * 2 }
39
+ }
40
+ )
41
+
42
+ const tape = new RecordTape<{ value: number }, { result: number }>({})
43
+
44
+ task.addListener<{ value: number }, { result: number }>((record) => {
45
+ const logItem: LogItem<{ value: number }, { result: number }> = record.error
46
+ ? { input: record.input, error: record.error, boundaries: record.boundaries }
47
+ : { input: record.input, output: record.output as { result: number }, boundaries: record.boundaries }
48
+
49
+ tape.addLogItem('test', logItem)
50
+ })
51
+
52
+ try {
53
+ await task.run({ value: 5 })
54
+ } catch (_error) {
55
+ // this is expected
56
+ }
57
+
58
+ await task.run({ value: 15 })
59
+
60
+ const log = tape.getLog()
61
+
62
+ expect(log).toEqual([
63
+ { name: 'test', type: 'error', input: { value: 5 }, error: 'Value is not between 10 and 20', boundaries: {} },
64
+ { name: 'test', type: 'success', input: { value: 15 }, output: { result: 30 }, boundaries: {} }
65
+ ])
66
+ })
67
+
68
+ it('Should get types from task', async () => {
69
+ // Create a schema for the task
70
+ const schema = new Schema({
71
+ value: Schema.number()
72
+ })
73
+
74
+ // Define the boundaries
75
+ const boundaries = {
76
+ multiply: async (value: number): Promise<number> => {
77
+ return value * 2
78
+ }
79
+ }
80
+
81
+ // Create the task using createTask
82
+ const task = createTask(
83
+ schema,
84
+ boundaries,
85
+ async (input, { multiply }) => {
86
+ const result = await multiply(input.value)
87
+ return { result }
88
+ }
89
+ )
90
+
91
+ type InputType = typeof schema
92
+ type OutputType = Awaited<ReturnType<typeof task.run>>
93
+
94
+ const tape = new RecordTape<InputType, OutputType>({})
95
+
96
+ task.addListener<InputType, OutputType>((record) => {
97
+ const logItem: LogItem<InputType, OutputType> = record.error
98
+ ? { input: record.input, error: record.error, boundaries: record.boundaries }
99
+ : { input: record.input, output: record.output as OutputType, boundaries: record.boundaries }
100
+
101
+ tape.addLogItem('test', logItem)
102
+ })
103
+
104
+ await task.run({ value: 5 })
105
+
106
+ expect(tape.getLog()).toEqual([
107
+ {
108
+ name: 'test',
109
+ type: 'success',
110
+ input: { value: 5 },
111
+ output: { result: 10 },
112
+ boundaries: {
113
+ multiply: [{ input: [5], output: 10 }]
114
+ }
115
+ }
116
+ ])
117
+ })
118
+
119
+ it('Should listen to task events with boundaries', async () => {
120
+ type InputType = { value: number }
121
+ type OutputType = { result: number }
122
+
123
+ const tape = new RecordTape<InputType, OutputType>({})
124
+
125
+ // Create a schema for the task
126
+ const schema = new Schema({
127
+ value: Schema.number()
128
+ })
129
+
130
+ // Define the boundaries
131
+ const boundaries = {
132
+ multiply: async (value: number): Promise<number> => {
133
+ return value * 2
134
+ }
135
+ }
136
+
137
+ // Create the task using createTask
138
+ const task = createTask(
139
+ schema,
140
+ boundaries,
141
+ async (input, { multiply }) => {
142
+ const result = await multiply(input.value)
143
+ return { result }
144
+ }
145
+ )
146
+
147
+ task.addListener<InputType, OutputType>((record) => {
148
+ const logItem: LogItem<InputType, OutputType> = record.error
149
+ ? { input: record.input, error: record.error, boundaries: record.boundaries }
150
+ : { input: record.input, output: record.output as OutputType, boundaries: record.boundaries }
151
+
152
+ tape.addLogItem('test', logItem)
153
+ })
154
+
155
+ await task.run({ value: 5 })
156
+
157
+ expect(tape.getLog()).toEqual([
158
+ {
159
+ name: 'test',
160
+ type: 'success',
161
+ input: { value: 5 },
162
+ output: { result: 10 },
163
+ boundaries: {
164
+ multiply: [{ input: [5], output: 10 }]
165
+ }
166
+ }
167
+ ])
168
+ })
169
+ })
170
+
package/tsconfig.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./dist",
5
+ "rootDir": "./src",
6
+ "composite": false,
7
+ "incremental": false,
8
+ "declaration": true,
9
+ "declarationMap": true,
10
+ "sourceMap": true
11
+ },
12
+ "include": [
13
+ "src/**/*"
14
+ ],
15
+ "exclude": [
16
+ "node_modules",
17
+ "dist"
18
+ ]
19
+ }