Skip to content

Commit 6da5e4a

Browse files
committed
fix(actions): discover installed action files
1 parent 9ebb7b4 commit 6da5e4a

2 files changed

Lines changed: 42 additions & 15 deletions

File tree

storage/framework/core/actions/src/helpers/utils.ts

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,32 @@ type ActionPath = string // TODO: narrow this by automating its generation
1414
type ActionName = string // TODO: narrow this by automating its generation
1515
type Action = ActionPath | ActionName | string
1616

17+
export function publishedActionCandidates(action: string, packageRoot?: string): string[] {
18+
let root = packageRoot
19+
20+
if (!root) {
21+
try {
22+
const pkgUrl = import.meta.resolve('@stacksjs/actions/package.json')
23+
if (pkgUrl) {
24+
const pkgPath = new URL(pkgUrl).pathname
25+
root = pkgPath.slice(0, pkgPath.lastIndexOf('/'))
26+
}
27+
}
28+
catch {
29+
return []
30+
}
31+
}
32+
33+
if (!root)
34+
return []
35+
36+
return [
37+
`${root}/dist/${action}.js`,
38+
`${root}/dist/src/${action}.js`,
39+
`${root}/src/${action}.ts`,
40+
]
41+
}
42+
1743
export function developmentConditionForProject(projectRoot: string): string {
1844
return existsSync(join(projectRoot, 'storage/framework/core'))
1945
&& existsSync(join(projectRoot, 'node_modules/@stacksjs/env/src/index.ts'))
@@ -56,20 +82,10 @@ async function resolveActionFile(action: string): Promise<string | null> {
5682
// 2/3) Find the @stacksjs/actions package root, then look for a built
5783
// action JS alongside its TS source. Wrapped in try/catch because
5884
// the package may not be installed at all in some layouts.
59-
try {
60-
const pkgUrl = import.meta.resolve('@stacksjs/actions/package.json')
61-
if (pkgUrl) {
62-
const pkgPath = new URL(pkgUrl).pathname
63-
const pkgRoot = pkgPath.slice(0, pkgPath.lastIndexOf('/'))
64-
// The build emits a flat `dist/` (root: './src'), so `dist/<action>.js`
65-
// is the current layout. `dist/src/<action>.js` is kept as a fallback for
66-
// older published packages that shipped the nested layout.
67-
candidates.push(`${pkgRoot}/dist/${action}.js`)
68-
candidates.push(`${pkgRoot}/dist/src/${action}.js`)
69-
candidates.push(`${pkgRoot}/src/${action}.ts`)
70-
}
71-
}
72-
catch { /* package not installed — skip, fall through to override only */ }
85+
// The build emits a flat `dist/` (root: './src'), so `dist/<action>.js`
86+
// is the current layout. `dist/src/<action>.js` is kept as a fallback for
87+
// older published packages that shipped the nested layout.
88+
candidates.push(...publishedActionCandidates(action))
7389

7490
for (const candidate of candidates) {
7591
if (await Bun.file(candidate).exists()) return candidate
@@ -271,6 +287,7 @@ export function hasAction(action: Action): boolean {
271287
const candidates = [
272288
...userActionPatterns.map(pattern => p.userActionsPath(pattern)),
273289
...actionPatterns.map(pattern => p.actionsPath(pattern)),
290+
...publishedActionCandidates(action),
274291
]
275292

276293
return candidates.some(candidate => existsSync(candidate))

storage/framework/core/actions/tests/helpers-utils.test.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
22
import { tmpdir } from 'node:os'
33
import { join } from 'node:path'
44
import { afterEach, describe, expect, it } from 'bun:test'
5-
import { developmentConditionForProject } from '../src/helpers/utils'
5+
import { developmentConditionForProject, publishedActionCandidates } from '../src/helpers/utils'
66

77
const roots: string[] = []
88

@@ -33,3 +33,13 @@ describe('developmentConditionForProject', () => {
3333
expect(developmentConditionForProject(root)).toBe('')
3434
})
3535
})
36+
37+
describe('publishedActionCandidates', () => {
38+
it('resolves flat, legacy nested, and source package layouts', () => {
39+
expect(publishedActionCandidates('bump', '/app/node_modules/@stacksjs/actions')).toEqual([
40+
'/app/node_modules/@stacksjs/actions/dist/bump.js',
41+
'/app/node_modules/@stacksjs/actions/dist/src/bump.js',
42+
'/app/node_modules/@stacksjs/actions/src/bump.ts',
43+
])
44+
})
45+
})

0 commit comments

Comments
 (0)