|
1 | | -import { z, ZodRecord, ZodString } from 'zod'; |
2 | | -import { SchemaInfo } from './middlewares/datasource'; |
| 1 | +import {z, ZodEnum, ZodRecord, ZodString} from 'zod'; |
| 2 | +import { SchemaInfo } from './middlewares/datasource.js'; |
3 | 3 |
|
4 | 4 | function getRequiredEnvVar(name: string) { |
5 | 5 | const property = process.env[name]; |
@@ -27,6 +27,15 @@ export const getRequiredString = (name: string): string => { |
27 | 27 | return stringValue.data; |
28 | 28 | }; |
29 | 29 |
|
| 30 | +export const getString = (name: string): string => { |
| 31 | + const value = process.env[name] || ''; |
| 32 | + const stringValue = z.string().safeParse(value); |
| 33 | + if (!stringValue.success) { |
| 34 | + throw new Error(`Environment variable ${name} in config is not a valid string`); |
| 35 | + } |
| 36 | + return stringValue.data; |
| 37 | +}; |
| 38 | + |
30 | 39 | export const getUrl = (name: string): string => { |
31 | 40 | const value = process.env[name] || 'a://'; |
32 | 41 | const stringValue = z.string().url().safeParse(value); |
@@ -56,73 +65,91 @@ export const getArray = (name: string): ZodString['_output'][] => { |
56 | 65 | } catch (e) { |
57 | 66 | throw new Error(`Environment variable ${name} is not valid. Please provide an array of strings.`) |
58 | 67 | } |
| 68 | +}; |
| 69 | + |
| 70 | +export const getEnum = <T extends [string, ...string[]]>(name: string, zEnum: ZodEnum<T>): z.infer<ZodEnum<T>> => { |
| 71 | + const stringValue = zEnum.safeParse(process.env[name]); |
| 72 | + if (!stringValue.success) { |
| 73 | + throw new Error(`Environment variable ${name} has an invalid value. Valid values are: ${zEnum.options}`); |
| 74 | + } |
| 75 | + return stringValue.data; |
| 76 | +}; |
59 | 77 |
|
| 78 | +export const validateArrayContents = <T extends [string, ...string[]]>(name: string, zEnum: ZodEnum<T>, value: string | undefined = ''): z.infer<ZodEnum<T>> => { |
| 79 | + const stringValue = zEnum.safeParse(value); |
| 80 | + if (!stringValue.success) { |
| 81 | + throw new Error(`Environment variable ${name} has an invalid value. Valid values are: ${zEnum.options}`); |
| 82 | + } |
| 83 | + return stringValue.data; |
60 | 84 | }; |
61 | 85 |
|
| 86 | + |
62 | 87 | export const getRecord = (name: string): ZodRecord<ZodString, ZodString> => { |
63 | 88 | const config_entry = `${name.toUpperCase()}_SEARCH`; |
64 | 89 | return z.record( |
65 | | - z.string({ invalid_type_error: 'Invalid key in ' + config_entry + '. Should be a string' }), |
66 | | - z.string({ invalid_type_error: 'Invalid value in ' + config_entry + '. Should be a string' }), |
| 90 | + z.string({ invalid_type_error: `Invalid key in ${config_entry}. Should be a string` }), |
| 91 | + z.string({ invalid_type_error: `Invalid value in ${config_entry}. Should be a string` }), |
67 | 92 | { invalid_type_error: `Environment variable ${config_entry} is invalid or missing` }, |
68 | 93 | ); |
69 | 94 | }; |
70 | 95 |
|
71 | 96 | export const getSchemaDef = (name: string): z.ZodType<SchemaInfo> => { |
72 | | - const config_entry = name.toUpperCase() + `_SCHEMA`; |
73 | | - return z.object( |
74 | | - { |
75 | | - tablename: z |
76 | | - .string({ |
77 | | - required_error: 'tablename in ' + config_entry + ' is required', |
78 | | - invalid_type_error: 'tablename in ' + config_entry + ' is invalid', |
79 | | - }) |
80 | | - .trim() |
81 | | - .min(1, { message: 'tablename in ' + config_entry + ' cannot be empty' }), |
82 | | - columns: z |
83 | | - .array( |
84 | | - z.object({ |
85 | | - name: z.string({ required_error: 'column `name` in ' + config_entry + ' is missing' }), |
86 | | - type: z.union( |
87 | | - [ |
88 | | - z.literal('float'), |
89 | | - z.literal('varchar'), |
90 | | - z.literal('number'), |
91 | | - z.literal('date'), |
92 | | - z.literal('varchar2'), |
93 | | - z.literal('string'), |
94 | | - z.literal('timestamp'), |
95 | | - z.literal('double'), |
96 | | - z.literal('boolean'), |
97 | | - ], |
98 | | - { |
99 | | - invalid_type_error: '`type` in ' + config_entry + ' has an invalid value.', |
100 | | - required_error: '`type` in ' + config_entry + ' is required.', |
101 | | - }, |
102 | | - ), |
103 | | - defaultValue: z |
104 | | - .string({ invalid_type_error: 'value for `defaultValue` in ' + config_entry + ' is invalid' }) |
105 | | - .optional(), |
106 | | - unique: z.boolean({ invalid_type_error: 'value for `unique` in ' + config_entry + ' is invalid' }).optional(), |
107 | | - }), |
108 | | - { |
109 | | - invalid_type_error: '`columns` in ' + config_entry + ' should be an array', |
110 | | - }, |
111 | | - ) |
112 | | - .nonempty({ message: '`column` array in ' + config_entry + ' should not be empty' }), |
113 | | - index: z |
114 | | - .array( |
115 | | - z.string({ |
116 | | - invalid_type_error: '`index` in ' + config_entry + ' is invalid. It should be a list of column name strings', |
117 | | - }), |
118 | | - { |
119 | | - invalid_type_error: '`index` in ' + config_entry + ' is invalid. It should be a list of column name strings', |
120 | | - required_error: '`index` in ' + config_entry + ' is missing.', |
121 | | - }, |
122 | | - ) |
123 | | - .nonempty({ message: '`index` in ' + config_entry + ' is required' }), |
124 | | - }, |
125 | | - { invalid_type_error: 'Schema definition missing for entity <' + name + '> in the ENTITY_LIST' }, |
126 | | - ); |
| 97 | + const config_entry = name.toUpperCase() + `_SCHEMA`; |
| 98 | + return z.object( |
| 99 | + { |
| 100 | + tablename: z |
| 101 | + .string({ |
| 102 | + required_error: 'table name in ' + config_entry + ' is required', |
| 103 | + invalid_type_error: 'table name in ' + config_entry + ' is invalid', |
| 104 | + }) |
| 105 | + .trim() |
| 106 | + .min(1, { message: 'table name in ' + config_entry + ' cannot be empty' }), |
| 107 | + columns: z |
| 108 | + .array( |
| 109 | + z.object({ |
| 110 | + name: z.string({ required_error: 'column name in ' + config_entry + ' is missing' }), |
| 111 | + type: z.union([ |
| 112 | + z.literal('float'), |
| 113 | + z.literal('varchar'), |
| 114 | + z.literal('number'), |
| 115 | + z.literal('date'), |
| 116 | + z.literal('varchar2'), |
| 117 | + z.literal('string'), |
| 118 | + z.literal('timestamp'), |
| 119 | + z.literal('double'), |
| 120 | + z.literal('boolean'), |
| 121 | + ]), |
| 122 | + defaultValue: z |
| 123 | + .string({ invalid_type_error: 'value for defaultValue in ' + config_entry + ' is invalid' }) |
| 124 | + .optional(), |
| 125 | + unique: z.boolean({ invalid_type_error: 'value for unique in ' + config_entry + ' is invalid' }).optional(), |
| 126 | + }), |
| 127 | + { |
| 128 | + invalid_type_error: 'columns in ' + config_entry + ' should be an array', |
| 129 | + }, |
| 130 | + ) |
| 131 | + .nonempty({ message: 'column array in ' + config_entry + ' should not be empty' }), |
| 132 | + index: z |
| 133 | + .array( |
| 134 | + z.array( |
| 135 | + z.string({ |
| 136 | + invalid_type_error: |
| 137 | + 'index in ' + config_entry + ' is invalid. It should be a list of column name strings', |
| 138 | + }), |
| 139 | + { |
| 140 | + invalid_type_error: |
| 141 | + 'index in ' + config_entry + ' is invalid. It should be a list of column name strings', |
| 142 | + required_error: 'index in ' + config_entry + ' is missing.', |
| 143 | + }, |
| 144 | + ), |
| 145 | + { |
| 146 | + invalid_type_error: |
| 147 | + 'index in ' + config_entry + ' is invalid. It should be a list of list of column name strings', |
| 148 | + required_error: 'index in ' + config_entry + ' is missing.', |
| 149 | + }, |
| 150 | + ) |
| 151 | + .nonempty({ message: 'index in ' + config_entry + ' is required' }), |
| 152 | + }, |
| 153 | + { invalid_type_error: 'Schema definition missing for entity <' + name + '> in the ENTITY_LIST' }, |
| 154 | + ); |
127 | 155 | }; |
128 | | - |
|
0 commit comments