-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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(boot): bind content of package.json to app context #1764
Conversation
@@ -53,6 +55,11 @@ export function BootMixin<T extends Constructor<any>>(superClass: T) { | |||
this.bind(BootBindings.BOOT_OPTIONS).toDynamicValue( | |||
() => this.bootOptions, | |||
); | |||
|
|||
this.bind(CoreBindings.APPLICATION_PACKAGE_JSON).toDynamicValue(() => { |
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.
Would it not be better for this to be done via a Booter
? This is not the intended usage of bootmixin
and seems like concerns are being mixed.
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 don't mind moving it to a application
booter in the future once we figure out our configuration loading story, such as how to deal with env vars.
d8180ef
to
30b4dcb
Compare
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.
LGTM overall. i'm ok leaving out an ApplicationBooter till we have more stuff to add to it. Just one last comment and this can land imo.
|
||
this.bind(CoreBindings.APPLICATION_PACKAGE_JSON).toDynamicValue(() => { | ||
const pkgFile = path.resolve(this.projectRoot, 'package.json'); | ||
return require(pkgFile); |
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.
Should we do a try/catch here in case package.json
path is resolved incorrectly or the file doesn't exist (not sure why that may happen ... but in case it does).
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.
Personally, I would much rather see this functionality implemented as a new booter class.
As far as I understand the current design, BooterMixin
is an optional helper that is not required for the booter component to work. Users should be able to use app.component(BooterComponent)
and still get fully functional bootstrapper.
@@ -21,6 +23,15 @@ describe('controller booter acceptance tests', () => { | |||
|
|||
afterEach(stopApp); | |||
|
|||
it('binds package.json', async () => { |
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.
Please move this test to a more appropriate file, maybe create a new test file in test/acceptance
directory?
It looks wrong to me to see package.json-related tests inside controller booter acceptance tests
.
(I think this is another clue that package.json should be handled by a new booter.)
packages/core/src/application.ts
Outdated
@@ -192,6 +192,10 @@ export class Application extends Context { | |||
const instance = this.getSync<Component>(componentKey); | |||
mountComponent(this, instance); | |||
} | |||
|
|||
public packageJson(pkg: PackageJson) { |
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 find this name confusing for users and readers.
app.packageJson(/*...*/);
Can we find a better name, for example setApplicationMetadata
? (I do realize this is not consistent with other API like app.component
or app.controller
.)
packages/core/src/application.ts
Outdated
/** | ||
* Type description for `package.json` | ||
*/ | ||
export interface PackageJson { |
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.
JSON is a serialization format. Can we replace it with something else in the interface name please? How about PackageManifest
, PackageMetadata
or even ApplicationManifest
/ApplicationMetadata
?
I think I like ApplicationMetadata
most.
packages/core/src/application.ts
Outdated
version: string; | ||
description: string; | ||
// tslint:disable-next-line:no-any | ||
[name: string]: any; |
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.
If this data object is typically loaded from JSON, then I think we should restrict the allowed property types to number | string | object | array | null
. JSON does not support functions and Dates for example. The current type definition makes it easy to accidentally treat a package.json property as a function and call it.
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.
If this data object is typically loaded from JSON, then I think we should restrict the allowed property types to
number | string | object | array | null
. JSON does not support functions and Dates for example. The current type definition makes it easy to accidentally treat a package.json property as a function and call it.
This comment hasn't been addressed nor responded to, PTAL.
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.
Fixed
30b4dcb
to
699b622
Compare
@bajtos I added a |
699b622
to
083d8d4
Compare
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.
The patch looks much better now!
packages/core/src/application.ts
Outdated
@@ -192,6 +192,16 @@ export class Application extends Context { | |||
const instance = this.getSync<Component>(componentKey); | |||
mountComponent(this, instance); | |||
} | |||
|
|||
/** | |||
* Set application metadata. By default, the content of `package.json` is |
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.
"By defaults" implies to me that package.json
metadata is populated by Application constructor, which is not true.
Can we make it more clear please that this metadata is empty by default but @loopback/boot
populates is from package.json
?
packages/core/src/application.ts
Outdated
version: string; | ||
description: string; | ||
// tslint:disable-next-line:no-any | ||
[name: string]: any; |
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.
If this data object is typically loaded from JSON, then I think we should restrict the allowed property types to
number | string | object | array | null
. JSON does not support functions and Dates for example. The current type definition makes it easy to accidentally treat a package.json property as a function and call it.
This comment hasn't been addressed nor responded to, PTAL.
65ba761
to
9424a11
Compare
@bajtos Fixed. PTAL. |
9424a11
to
f104c29
Compare
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.
LGTM.
Please double check that the tests are passing after rebasing your changes on top of the latest master
.
@@ -33,6 +33,7 @@ describe('controller booter acceptance tests', () => { | |||
}); | |||
|
|||
async function getApp() { | |||
await sandbox.copyFile(resolve(__dirname, '../fixtures/package.json')); |
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 this will not work after the changes I made in #1824) - the package.json
file is not going to be copied over from test
to dist/test
.
I think the easiest solution is to load the package json file from test/fixtures/application.ts
:
import * as pkg from './package.json'
f104c29
to
c111fba
Compare
See loopbackio/loopback4-example-shopping#16 (comment)
Checklist
npm test
passes on your machinepackages/cli
were updatedexamples/*
were updated