refs: cf514cdf7
- in commit cf514cdf7 we moved the loadSettings call up to the bridge
- here we can call the async method, so we can remove loadSettingsSync altogether
- all the tests have now been changed to use the async method
- following on from removing api versioning logic from the frontend, it's possible to make more sense of what's happening
- this commit first introduces a proper jsdoc'd object that gets passed through the frontent load & reload flow
- that object contains the urlService and optionally our routeSettings processed from routes.yaml
- additionally, we were passing around a start boolean, which told the routerManager whether to just init, or init+start
- with this refactor, we always pass in the routeSettings when we want to do init+start, so we no longer need a boolean
- The refactor itself moves logic from the reload function in site.js and urlservice + routesettings fetching logic from routes.js
into the reloadFrontend function in bridge.js.
- This makes it clearer to see what happens when we call reloadFrontend.
- This commit also makes it clearer to see what is happening with the route settings, where they are needed and why
- Ideally we'd also clean up the weird dupliated logic and somewhat unnecessary routes.js file
refs: https://github.com/TryGhost/Toolbox/issues/228
- we are getting rid of the concept of api versions from Ghost
- this means getting rid of them from the frontend as well, and from themes
- Ghost themes are allowed to define the API version they want to use, but this concept has never really worked correctly
- We have a theory that it doesn't ever do quite what people want, and so always loading latest would not really break anything - this commit tests that theory
- We're pinning to canary, as we're aiming to get rid of the concept of versions altogether
- I could have done return config.get('api:versions:default');, but this actually returns v4 (although the same as canary, conceptually different)
and it also seemed like an unnecessary level of indirection. This change should be easy to understand and to revert if we are wrong
- throughout the theme activation flow there are several missing awaits and necessary async keywords
- we should be waiting on these processes, not letting them complete indeterministically
- Card asset reloading was incorrectly only happening if the API version changed 🙈
- In addition, having an init function was redundant, as theme activation happens on boot
- This meant that the card assets were being generated twice on boot
- Instead, we now only generate them on theme activation, which covers the boot case and simplifies all the logic
refs https://github.com/TryGhost/Toolbox/issues/135
- The reason the test **settings** test was failing when the force start flag was removed in the **custom themes** was the bridge! The bridge was trying to execute function on the frontend when the boot was done without initializing the frontend. The setting test was changing locale and the timezone which triggered events calling up on frontend components - we clearly don't want to do this when the instance is booted without the frontend
- To make event initialization conditional moved it to the "init". This way the event listeners are only set up when we boot with the "frontend" flag set to true
- Requires the new @tryghost/minifier package
- Adds a new service that will handle taking config from the theme and optionally including assets for Koenig editor cards
- It supports both css and js as cards may need one or both
- For any given config, the tool can find the matching files to include and concat and minify them into one file per type
- Currently has an override in place so that this is not yet customisable in the theme - will remove this override when we're ready for the feature
- we're slowly trying to draw the lines between the backend and the frontend correctly
- these files deal only with serving the frontend so they should live there
- there are lots of mixed requires in these files, so having them in the right place makes that clear
refs https://linear.app/tryghost/issue/CORE-104/decouple-frontend-routing-events-from-urlserver-events
- The "bootstrap" didn't give enough credit to everything this module was doing - it's responsible for managing correct initialization and reinitialization of the frontend Routes as well as passing router creation information back to the frontend's URL service
- The refactor is done in two steps - the "bootstrap.js" will be renamed in the follow-up commit to have a clean history of how the file evolved
refs https://linear.app/tryghost/issue/CORE-104/decouple-frontend-routing-events-from-urlserver-events
- The 'settings.timezone.edited' event triggers a roundtrip chain of calls in the frontend routing to the url services. It was all handled by event listeners and handler that clearly don't belong there.
- Extracted event realted listeners/handlers into methods and moved most of the logic to the "bootstrap" module, which soon is going to become a "RoutesManger"
- The result of this refactor - no more events going back and forth between frontend routing and the backend!
- This is a precursor to trying to split apart into:
- model events + webhooks system which makes sense
- frontend events which should be independent or removed
- maybe some concept of a settings manager that we can use in various places to bind logic 🤔
- other usages of events that should be refactored to not use events
- The router bootstrap is no longer allowed to fetch it's own settings, but rather is passed them
- This moves the call to the site routes.js file, which isn't much better but it's a start
- The goal is to always pass these in from the boot process, or from the bridge reloader
- Reduced the number of levels in our debug naming in the frontend
- Unified components like "themes" and "routing" under one name
- Should help to make debug slightly more useful again
- This is part of the quest to separate the frontend and server & get rid of all the places where there are cross-requires
- At the moment the settings cache is one big shared cache used by the frontend and server liberally
- This change doesn't really solve the fundamental problems, as we still depend on events, and requires from inside frontend
- However it allows us to control the misuse slightly better by getting rid of restricted requires and turning on that eslint ruleset
- Allows for slight decoupling of API and frontend with route settings being updated
- Activate theme now calls the same codepath to reload the frontend
- Yet another step on the path to make it possible to init/reload/run the frontend independently from the server
- Traditionally all of Ghost's public-facing text was written in British English
- We're changing that to US English because that's more common
- US English should also be used in code e.g. properties are called color not colour
- most of these changes are in comments, but I've changed them so that we have US English in front of us always
- fixed a few other typos I noticed whilst there
- when activating a theme, we need to load the current locale
- this request used to be buried deep in the themeI18n init call
- now we surface it in the bridge and pass it down, which is closer to what we want to do with eventually initialising the frontend
with everything it needs up front (or not initialising it, if it isn't needed)
- in the related helpers we depend on the site.locale value instead of proxy -> themeI18n -> settingsCache drastically simplifying the code and removing deep requires
- site.locale is updated via middleware and can be relied upon
refs 829e8ed010
- i18n is used everywhere but only requires shared or external packages, therefore it's a good candidate for living in shared
- this reduces invalid requires across frontend and server, and lets us use it everywhere until we come up with a better option
- Having these as destructured from the same package is hindering refactoring now
- Events should really only ever be used server-side
- i18n should be a shared module for now so it can be used everywhere until we figure out something better
- Having them seperate also allows us to lint them properly
refs: bf0823c9a2
- continuing the work of splitting up the theme service into logical components
Theme activations are a trickier piece of the theme split puzzle because they are called from the API and theme service on boot in different ways.
Activations require a theme to have been validated at different levels. Validations are also tricky - do they belong to the theme engine, or the theme service?
There are then several different flows for activations:
- On Boot
- API "activate" call
- API override on upload or install via setFromZip, which is a method in the storage layer
These calls all have quite different logical flows at the moment, and need to be unified
For now, I've moved the existing "activate" function onto the bridge. This allows the theme service to be split from the frontend, and refactoring can start from there.
I hope to move this so there is less code in the actual bridge very soon, but my goal is not to require any server packages in the frontend part of this
I think ideally:
- all activation code, including validation, should probably be part of the theme engine
- the theme engine should offer 3 methods: getActive() canActivate() and activate()
- the theme service is then only responsible for loading themes in and out of storage, JSON responses for the API, and handing themes to the frontend via the bridge at the appropriate moment
- Modules in /shared are supposed to be standalone modules that can be required by the server or frontend
- As the server shouldn't require the frontend, and vice versa, shared modules should require neither
- Otherwise it just becomes a crutch for allowing cross-depenencies, and will create circular dependencies
The Bridge
- The bridge file is not meant to be a crutch sat allowing cross-dependencies, but rather a new component that manages the flow of data
- That data flows from the server/boot process TO the frontend, and should not flow in the other direction
- The management of that flow of data is necessarily hacky at the moment, but over time the architecture here should get clearer and better
- Still, for the time being it will need to handle requiring across components until that architecture matures
- Therefore, it should live in core root, not in core/shared