-
-
Notifications
You must be signed in to change notification settings - Fork 186
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: load modelina configuration options from a config file #1367
Changes from 7 commits
e7d4377
89a24c0
69c83ab
a16426a
e53bc72
fc9d9fe
e95d6c6
3c5331e
a207ca2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# Get config from file | ||
|
||
An example of using the `getConfigFromFile` function. We get the config from a file and pass it to a `TypescriptGenerator` | ||
|
||
## How to run this example | ||
|
||
Run this example using: | ||
|
||
```sh | ||
npm i && npm run start | ||
``` | ||
|
||
If you are on Windows, use the `start:windows` script instead: | ||
|
||
```sh | ||
npm i && npm run start:windows | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
const spy = jest.spyOn(global.console, 'log').mockImplementation(() => { | ||
return; | ||
}); | ||
|
||
describe('Should be able to render', () => { | ||
afterAll(() => { | ||
jest.restoreAllMocks(); | ||
}); | ||
test('and should log expected output to console', () => { | ||
expect(spy.mock.calls.length).toEqual(1); | ||
expect(spy.mock.calls[0]).toMatchSnapshot(); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { FileHelpers, TypeScriptGenerator, TypeScriptOptions } from '../../src'; | ||
|
||
const jsonSchemaDraft7 = { | ||
$schema: 'http://json-schema.org/draft-07/schema#', | ||
type: 'object', | ||
additionalProperties: false, | ||
properties: { | ||
email: { | ||
type: 'string', | ||
format: 'email' | ||
} | ||
} | ||
}; | ||
|
||
async function main() { | ||
try { | ||
const config: { config: TypeScriptOptions } = | ||
await FileHelpers.getConfigFromFile('./modelina.config.alternate.js'); | ||
const tsGen = new TypeScriptGenerator(config.config); | ||
const models = await tsGen.generate(jsonSchemaDraft7); | ||
for (const model of models) { | ||
console.log(model.result); | ||
} | ||
} catch (err) { | ||
console.log(err); | ||
} | ||
} | ||
|
||
main(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { | ||
TS_COMMON_PRESET, | ||
IndentationTypes, | ||
TypeScriptOptions | ||
} from '../../src'; | ||
|
||
/** @type {TypeScriptOptions} */ | ||
const config = { | ||
enumType: 'union', | ||
modelType: 'interface', | ||
indentation: { | ||
size: 10, | ||
type: IndentationTypes.SPACES | ||
}, | ||
mapType: 'record', | ||
renderTypes: false, | ||
moduleSystem: 'CJS', | ||
constraints: { | ||
modelName: (context) => { | ||
return `Custom${context.modelName}`; | ||
}, | ||
propertyKey: (context) => { | ||
return `custom_prop_${context.objectPropertyModel.propertyName}`; | ||
} | ||
}, | ||
typeMapping: { | ||
Any: (context) => { | ||
// Always map AnyModel to number | ||
return 'number'; | ||
} | ||
}, | ||
presets: [ | ||
{ | ||
preset: TS_COMMON_PRESET, | ||
options: { | ||
example: true | ||
} | ||
}, | ||
{ | ||
preset: TS_COMMON_PRESET, | ||
options: { | ||
marshalling: true | ||
} | ||
} | ||
] | ||
}; | ||
|
||
export { config }; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { | ||
TS_COMMON_PRESET, | ||
IndentationTypes, | ||
TypeScriptOptions | ||
} from '../../src'; | ||
|
||
/** @type {TypeScriptOptions} */ | ||
const config = { | ||
enumType: 'union', | ||
modelType: 'class', | ||
indentation: { | ||
size: 10, | ||
type: IndentationTypes.SPACES | ||
}, | ||
mapType: 'record', | ||
renderTypes: false, | ||
moduleSystem: 'CJS', | ||
constraints: { | ||
modelName: (context) => { | ||
return `Custom${context.modelName}`; | ||
}, | ||
propertyKey: (context) => { | ||
return `custom_prop_${context.objectPropertyModel.propertyName}`; | ||
} | ||
}, | ||
typeMapping: { | ||
Any: (context) => { | ||
// Always map AnyModel to number | ||
return 'number'; | ||
} | ||
}, | ||
presets: [ | ||
{ | ||
preset: TS_COMMON_PRESET, | ||
options: { | ||
example: true | ||
} | ||
}, | ||
{ | ||
preset: TS_COMMON_PRESET, | ||
options: { | ||
marshalling: true | ||
} | ||
} | ||
] | ||
}; | ||
|
||
export { config }; |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"config" : { "example_name" : "get-config-from-file" }, | ||
"scripts": { | ||
"install": "cd ../.. && npm i", | ||
"start": "../../node_modules/.bin/ts-node --cwd ../../ ./examples/$npm_package_config_example_name/index.ts", | ||
"start:windows": "..\\..\\node_modules\\.bin\\ts-node --cwd ..\\..\\ .\\examples\\%npm_package_config_example_name%\\index.ts", | ||
"test": "../../node_modules/.bin/jest --config=../../jest.config.js ./examples/$npm_package_config_example_name/index.spec.ts", | ||
"test:windows": "..\\..\\node_modules\\.bin\\jest --config=..\\..\\jest.config.js examples/%npm_package_config_example_name%/index.spec.ts" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -64,4 +64,18 @@ export class FileHelpers { | |
} | ||
}); | ||
} | ||
|
||
static async getConfigFromFile(configPath: string): Promise<any> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You have to write some unit tests here 🙂 Make sure you test error states as well:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make sure you document this function as well i.e. what it does 🙂 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jonaslagoni
and
Should be the same thing right ? I mean we wouldn't know if the file is exposing the config the right way, unless we know what it's exposing ? 🤔 The way i put it here might be confusing, feel free to ignore this, i will let you know later more context on this. 🙂 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll try fixing things one after other and contact you back 😄 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The first one is a bit hard to pull off, which is they expose the configuration correctly, but the configuration is incorrect (not sure we actually can do this) The second one is if they expose it like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'll try to see if we can do the first one
I'll look into this as well 🙂 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can restrict the users to only allow them to use js file for config right ? i hardly saw places where people used ts files for config. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree 👍 It can also be an improvement down the line if ever requested 🙂 |
||
const configFilePath = path.resolve(configPath); | ||
try { | ||
await fs.stat(configFilePath); | ||
} catch (err) { | ||
throw new Error( | ||
`No file exists on the specified location ${configFilePath}` | ||
); | ||
} | ||
|
||
const configOptions = require(configFilePath); | ||
return configOptions; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should simplify this.
Instead of having to do something like
config.config
, what do you think? 🤔There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah definitely, it looks absurd.
We can directly export the config. 🙂
Would that work ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep 👍