Skip to content

Commit 4f9abf6

Browse files
authored
Chore/dependency update 2026 04 25 di (#13)
* updated / fixed api breaks * filled changelogs * patcher fix * status manager update * playwright test match fix * updated collection sync to mitigate user context bug
1 parent 8ce2982 commit 4f9abf6

190 files changed

Lines changed: 2698 additions & 1918 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<!-- version-type: patch -->
2+
# common
3+
4+
## ⬆️ Dependencies
5+
6+
- Bumped `@furystack/core` from `^16.0.4` to `^17.0.0` and `@furystack/rest` from `^9.0.0` to `^10.0.0` to align with the monorepo-wide functional-DI migration in the `service` and `frontend` packages.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!-- version-type: patch -->
2+
# frontend
3+
4+
## ♻️ Refactoring
5+
6+
### Migrated to functional dependency injection (FuryStack v7)
7+
8+
Aligned the frontend with `@furystack/inject@^13` and the v7 majors of `core`, `cache`, `logging`, `rest-client-fetch`, `entity-sync-client`, `shades`, `shades-common-components`, and `shades-mfe`. No user-visible behavior change; the wire-up is now token-based.
9+
10+
**Highlights:**
11+
12+
- Converted all eight API clients (`identity-api-client`, `install-api-client`, `system-api-client`, `stacks-api-client`, `services-api-client`, `tokens-api-client`, `github-repos-api-client`, `prerequisites-api-client`) to the `class *Impl` + `defineService` token + `type` alias pattern, preserving the existing `injector.get(X).call(...)` and `private foo: X` consumer APIs.
13+
- Same conversion for `SessionService`, `InstallService`, and `EnvironmentVariableService`. `SessionService` now auto-calls `init()` from its constructor so that `injector.get(SessionService)` at startup eagerly probes the auth state (matches the previous behavior tests rely on).
14+
- Added `frontend/src/services/entity-sync.ts`: declares `AppEntitySyncService` via `defineEntitySyncService` and exports `useEntitySync` / `useCollectionSync` from `createSyncHooks(AppEntitySyncService)`. Replaces the root-exported hooks from `@furystack/entity-sync-client@^2`, which are gone.
15+
- Simplified `components/layout/layout.tsx`: dropped the manual `new EntitySyncService(...)` + `useDisposable` registration in favour of `injector.get(AppEntitySyncService)`; disposal now happens through the injector lifecycle.
16+
- Replaced every `injector.getInstance(X)` with `injector.get(X)` and every `injector.setExplicitInstance(value, Token)` with `injector.bind(Token, () => value)` (specs included).
17+
18+
## 🧪 Tests
19+
20+
- Spec setups (`session.spec`, `install-service.spec`, `environment-variable-service.spec`, `service-detail/utils.spec`) use `createInjector()` + `bind` for mock wiring instead of the removed `new Injector()` + `setExplicitInstance`.
21+
22+
## ⬆️ Dependencies
23+
24+
- Updated FuryStack stack to the v7 functional-DI majors:
25+
- `@furystack/cache` `^6.1.5``^7.0.0`
26+
- `@furystack/core` `^16.0.4``^17.0.0`
27+
- `@furystack/entity-sync` `^1.0.11``^2.0.0`
28+
- `@furystack/entity-sync-client` `^2.0.5``^3.0.0`
29+
- `@furystack/inject` `^12.0.36``^13.0.0`
30+
- `@furystack/logging` `^8.1.5``^9.0.0`
31+
- `@furystack/rest-client-fetch` `^8.1.8``^9.0.0`
32+
- `@furystack/shades` `^14.0.0``^15.0.0`
33+
- `@furystack/shades-common-components` `^16.0.0``^17.0.0`
34+
- `@furystack/shades-mfe` `^4.0.0``^5.0.0`
35+
- `@furystack/utils` `^8.2.5``^9.0.0`
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<!-- version-type: patch -->
2+
# service
3+
4+
## ♻️ Refactoring
5+
6+
### Migrated to functional dependency injection (FuryStack v7)
7+
8+
Swapped the entire backend over to the token-based DI surface introduced by `@furystack/inject@^13`, `@furystack/core@^17`, and the v7 majors of `repository`, `security`, `sequelize-store`, `rest-service`, `entity-sync-service`, `websocket-api`, and `logging`. No external API of the deployed service changed; this is an internal restructure.
9+
10+
**Highlights:**
11+
12+
- Replaced every `@Injectable` / `@Injected` class with a `defineService` token wrapping a constructor-injection `*Impl` class. The exported name (e.g. `ProcessManager`, `GitService`, `ServiceStatusManager`) is now the token; consumers continue to call `injector.get(X)` and use the resolved instance the same way.
13+
- Moved all stores and DataSets into the new `service/src/app-models/data-store/tokens.ts` module, declared with `defineSequelizeStore` / `defineStore` / `defineDataSet`. Authentication stores (`UserStore`, `SessionStore`, `PasswordCredentialStore`, `PasswordResetTokenStore`) are wired to the persistent sequelize-backed implementations through the new `bindAuthenticationStores(injector)` helper.
14+
- Switched `WebsocketService.init` from `useWebsockets` to `useWebSocketApi` and started accepting `SyncSubscribeAction` / `SyncUnsubscribeAction` as plain action descriptors.
15+
- Replaced the deleted `ServerManager` plumbing in `service.ts` and `shutdown-handler.ts` with the new `HttpServerPoolToken`; injector disposal now closes every pooled HTTP server.
16+
- Replaced `useSequelize` in the patcher with a `defineSequelizeStore`-backed `PatchRunStoreToken` + `PatchRunDataSet`, eagerly resolved in `setupPatcher` to keep model initialization compatible with downstream patches.
17+
- Reworked `health-check-action.ts` to resolve the database client through `SequelizeClientFactory` instead of the removed `injector.cachedSingletons` API.
18+
- `setupIdentityRestApi` now relies on the default `UserDataSet` from `@furystack/rest-service` (backed by our `AppUserStore` through `bindAuthenticationStores`) and drops the old `{ model: User }` argument to `useHttpAuthentication`.
19+
- `mcp/user-identity-context.ts`: `IdentityContext` is now an interface; `UserIdentityContext` implements it directly and is bound via `injector.bind` instead of `setExplicitInstance`.
20+
- Repository call sites (`getRepository(injector).getDataSetFor(Model, 'pk')`) are preserved through a dedicated `service/src/utils/legacy-repository.ts` shim that resolves the matching DataSet token by model identity, keeping action and service code unchanged.
21+
- Endpoint generators (`createGetCollectionEndpoint`, `createPostEndpoint`, etc.) now receive `DataSetToken`s in `setupGitHubReposRestApi` and `setupPrerequisitesRestApi`.
22+
23+
### Fixed a status-update race in `OneShotCommandRunner`
24+
25+
`runOneShot` previously fire-and-forgot the final `updateServiceStatus(installed/built)` call before resolving the install/build promise. Callers awaiting the runner could read the status while it was still `installing` / `building`. The exit / error handlers now await the status update before settling the returned promise.
26+
27+
## 🧪 Tests
28+
29+
- Added `service/src/test-shims.ts`: deprecation shim for the removed decorator-era APIs (`addStore`, `getStoreManager`, `injector.setExplicitInstance`, `injector.cachedSingletons`) so legacy spec setups continue to compile and run against the new functional DI surface.
30+
- Updated `request-logger.spec.ts` to spy on a custom backend logger (via `createLogger`) instead of `LoggerCollection.verbose`, which is no longer reachable from `withScope(...)` in `@furystack/logging@^9`.
31+
- Patcher tests (`check-for-orphaned-patch.spec.ts`, `run-patch.spec.ts`, `setup-patcher.spec.ts`) now use `useSystemIdentityContext` for elevation against authorized DataSets and bind the `PatchRunStoreToken` directly.
32+
- `health-check-action.spec.ts` binds a stub `SequelizeClientFactory` and seeds `DATABASE_URL` per test instead of populating `injector.cachedSingletons`.
33+
- `crypto-service`, `env-encryption-helpers`, and `filtered-console-logger` tests instantiate `*Impl` classes / resolve the logger token rather than the now-tokenized exports.
34+
35+
## 📦 Build
36+
37+
- `setup-patcher.ts` and `app-models/data-store/tokens.ts` build their `defineSequelizeStore` options through a lazy `Proxy` over `getDbOptions()` so importing the module no longer requires `DATABASE_URL` at load time (unblocks unit tests and tooling).
38+
39+
## ⬆️ Dependencies
40+
41+
- Updated FuryStack stack to the v7 functional-DI majors:
42+
- `@furystack/core` `^16.0.4``^17.0.0`
43+
- `@furystack/inject` `^12.0.36``^13.0.0`
44+
- `@furystack/logging` `^8.1.5``^9.0.0`
45+
- `@furystack/repository` `^10.1.11``^11.0.0`
46+
- `@furystack/rest-service` `^13.0.0``^14.0.0`
47+
- `@furystack/security` `^7.0.9``^8.0.0`
48+
- `@furystack/sequelize-store` `^6.0.49``^7.0.0`
49+
- `@furystack/websocket-api` `^13.2.8``^14.0.0`
50+
- `@furystack/entity-sync-service` `^1.0.13``^2.0.0`
51+
- Bumped dev `@types/node` to `^25.6.0`, `typescript` to `^6.0.3`, and `vitest` to `^4.1.5`.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<!-- version-type: patch -->
2+
# stack-craft
3+
4+
## ⬆️ Dependencies
5+
6+
- Updated `@furystack/eslint-plugin` from `^2.2.0` to `^3.0.0`. The new release drops the obsolete `injectable-consistent-inject` and `no-direct-physical-store` rules and adds `no-direct-store-token`, which is automatically enabled through the `recommendedStrict` preset already configured in `eslint.config.js` — no changes required to the workspace ESLint config.

.yarn/versions/f660e93d.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
releases:
2+
common: patch
3+
frontend: patch
4+
service: patch
5+
stack-craft: patch

common/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"vitest": "^4.1.5"
3131
},
3232
"dependencies": {
33-
"@furystack/core": "^16.0.4",
34-
"@furystack/rest": "^9.0.0"
33+
"@furystack/core": "^17.0.0",
34+
"@furystack/rest": "^10.0.0"
3535
}
3636
}

frontend/package.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,17 @@
1818
"vitest": "^4.1.5"
1919
},
2020
"dependencies": {
21-
"@furystack/cache": "^6.1.5",
22-
"@furystack/core": "^16.0.4",
23-
"@furystack/entity-sync": "^1.0.11",
24-
"@furystack/entity-sync-client": "^2.0.5",
25-
"@furystack/inject": "^12.0.36",
26-
"@furystack/logging": "^8.1.5",
27-
"@furystack/rest-client-fetch": "^8.1.8",
28-
"@furystack/shades": "^14.0.0",
29-
"@furystack/shades-common-components": "^16.0.0",
30-
"@furystack/shades-mfe": "^4.0.0",
31-
"@furystack/utils": "^8.2.5",
21+
"@furystack/cache": "^7.0.0",
22+
"@furystack/core": "^17.0.0",
23+
"@furystack/entity-sync": "^2.0.0",
24+
"@furystack/entity-sync-client": "^3.0.0",
25+
"@furystack/inject": "^13.0.0",
26+
"@furystack/logging": "^9.0.0",
27+
"@furystack/rest-client-fetch": "^9.0.0",
28+
"@furystack/shades": "^15.0.0",
29+
"@furystack/shades-common-components": "^17.0.0",
30+
"@furystack/shades-mfe": "^5.0.0",
31+
"@furystack/utils": "^9.0.0",
3232
"common": "workspace:^"
3333
}
3434
}

frontend/src/components/branch-selector.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,8 @@ export const BranchSelector = Shade<BranchSelectorProps>({
224224
const [isLoading, setIsLoading] = useState('isLoading', false)
225225
const [isCheckingOut, setIsCheckingOut] = useState('isCheckingOut', false)
226226

227-
const api = injector.getInstance(ServicesApiClient)
228-
const noty = injector.getInstance(NotyService)
227+
const api = injector.get(ServicesApiClient)
228+
const noty = injector.get(NotyService)
229229

230230
const hasBranchInfo = Boolean(currentBranch)
231231
const isClonedOrPulling = cloneStatus === 'cloned' || (cloneStatus === 'cloning' && hasBranchInfo)

frontend/src/components/bulk-action-bar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ type BulkActionBarProps = {
1212
export const BulkActionBar = Shade<BulkActionBarProps>({
1313
customElementName: 'shade-bulk-action-bar',
1414
render: ({ props, injector, useObservable, useState }) => {
15-
const api = injector.getInstance(ServicesApiClient)
16-
const noty = injector.getInstance(NotyService)
15+
const api = injector.get(ServicesApiClient)
16+
const noty = injector.get(NotyService)
1717

1818
const [selection] = useObservable('selection', props.collectionService.selection)
1919
const [isBulkLoading, setIsBulkLoading] = useState('isBulkLoading', false)

frontend/src/components/environment-variables-manager.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useCollectionSync } from '@furystack/entity-sync-client'
1+
import { useCollectionSync } from '../services/entity-sync.js'
22
import { createComponent, Shade } from '@furystack/shades'
33

44
import {
@@ -77,7 +77,7 @@ export const EnvironmentVariablesManager = Shade<EnvironmentVariablesManagerProp
7777
if (envPrereqs.length > 0 && !hasChecked) {
7878
const varNames = [...prereqVarNames]
7979
void injector
80-
.getInstance(EnvironmentVariableService)
80+
.get(EnvironmentVariableService)
8181
.checkAvailability(varNames)
8282
.then((result) => {
8383
setEnvAvailability(result)
@@ -89,7 +89,7 @@ export const EnvironmentVariablesManager = Shade<EnvironmentVariablesManagerProp
8989
const handleSave = async () => {
9090
setIsSaving(true)
9191
try {
92-
const toSave = injector.getInstance(EnvironmentVariableService).buildSavePayload(editState, touchedSensitive)
92+
const toSave = injector.get(EnvironmentVariableService).buildSavePayload(editState, touchedSensitive)
9393
props.onSave(toSave)
9494
} finally {
9595
setIsSaving(false)
@@ -104,7 +104,7 @@ export const EnvironmentVariablesManager = Shade<EnvironmentVariablesManagerProp
104104
try {
105105
if (mode === 'requirement') {
106106
const newId = crypto.randomUUID()
107-
await injector.getInstance(PrerequisitesApiClient).call({
107+
await injector.get(PrerequisitesApiClient).call({
108108
method: 'POST',
109109
action: '/prerequisites',
110110
body: {
@@ -116,7 +116,7 @@ export const EnvironmentVariablesManager = Shade<EnvironmentVariablesManagerProp
116116
installationHelp: '',
117117
},
118118
})
119-
injector.getInstance(NotyService).emit('onNotyAdded', {
119+
injector.get(NotyService).emit('onNotyAdded', {
120120
title: 'Prerequisite created',
121121
body: `Environment variable requirement "${variableName}" was added.`,
122122
type: 'success',
@@ -135,7 +135,7 @@ export const EnvironmentVariablesManager = Shade<EnvironmentVariablesManagerProp
135135
setAddFormState({ ...defaultAddFormState })
136136
setIsAddFormOpen(false)
137137
} catch (error) {
138-
injector.getInstance(NotyService).emit('onNotyAdded', {
138+
injector.get(NotyService).emit('onNotyAdded', {
139139
title: 'Error',
140140
body: error instanceof Error ? error.message : 'Failed to add environment variable',
141141
type: 'error',

0 commit comments

Comments
 (0)