mirror of
https://github.com/InvoiceShelf/InvoiceShelf.git
synced 2026-07-16 22:05:20 +00:00
* fix(deps): require invoiceshelf/modules ^3.0.2 (adds registerExchangeRateDriver)
DriverRegistryProvider::registerExchangeRateDrivers() calls
Registry::registerExchangeRateDriver(), which only exists in
invoiceshelf/modules >= 3.0.2. The constraint (^3.0) and the committed
lock (3.0.1) allowed/pinned versions without it, so a fresh
`composer install` (CI, Docker, new clones) boots into:
Call to undefined method InvoiceShelf\Modules\Registry::registerExchangeRateDriver()
Pin to ^3.0.2 and update the lock so every install gets a version that
has the method. `php artisan package:discover` verified clean.
* fix(ai): register the AI driver via the generic Registry::registerDriver('ai', ...)
registerAiDriver() is a convenience wrapper that is NOT present in any
published invoiceshelf/modules release (only the generic registerDriver()
and registerExchangeRateDriver() ship), so DriverRegistryProvider crashed
app boot on a clean composer install:
Call to undefined method InvoiceShelf\Modules\Registry::registerAiDriver()
Use registerDriver('ai', 'openrouter', ...) instead -- it stores under the
'ai' type exactly like the wrapper would, and AiConfigurationService /
AiDriverFactory read it back via allDrivers('ai') / driverMeta('ai', ...).
Verified by clean-reinstalling invoiceshelf/modules (no local patch) and
running `php artisan package:discover` -> boots clean.
* style: fix pre-existing Pint violations in backup services
BackupService.php and BackupConfigurationFactory.php (untouched by this
PR's boot fix) carried style violations from an earlier domain-reorg
refactor (6d1816bd). `pint --test` checks the whole tree and runs on any
PR that touches PHP, so these failed CI here. Auto-fixed with Pint
(braces_position, no_unused_imports, single_line_empty_body) so the check
goes green.
* build(deps): pull invoiceshelf/modules ^3.0.3 via VCS, restore registerAiDriver()
The 3.0.3 release adds Registry::registerAiDriver() (the method DriverRegistryProvider
and AiDriverFactoryTest call). Packagist has the package frozen, so resolve it directly
from the canonical GitHub repo via a composer VCS repository and require ^3.0.3 (the tag
exists; the freeze is Packagist-side only).
Now that the method ships, restore DriverRegistryProvider to Registry::registerAiDriver()
— reverting the temporary generic registerDriver('ai', ...) workaround — so it matches the
package's intended API and the existing tests. The provider is now net-identical to 3.x.
Verified: php artisan package:discover boots clean; the AI suite (incl. the previously
failing AiDriverFactoryTest) passes.
* test: provision modules_statuses.json in the test bootstrap
The Modules/HelloWorld integration test needs the module enabled at the nwidart
level, read from storage/app/modules_statuses.json at app boot. That file is
gitignored (created locally by `module:make`), so it's absent on CI and fresh
clones — HelloWorld stays disabled and the 5 integration tests fail with 404s.
Provision it (only if missing) in tests/Pest.php before any test boots the app,
so CI matches a local dev environment. Full suite: 462 pass.
* fix(test): enable HelloWorld via a committed modules_statuses.json
The Modules/HelloWorld integration test needs the module enabled at the nwidart
level — read from storage/app/modules_statuses.json by FileActivator. That file
is gitignored, so it's absent in CI / fresh clones, leaving HelloWorld disabled
and the 5 integration tests failing with 404s.
The previous tests/Pest.php provisioning (60a7f0d6) only worked under
`./vendor/bin/pest`. CI runs `php artisan test`, which boots the console app
first; FileActivator reads and caches the (absent) statuses at construction
BEFORE Pest.php runs, so test-runtime provisioning is too late. The file must
exist before any boot.
Commit the file via a storage/app/.gitignore negation, and revert the
ineffective Pest.php hack. Prod-safe: Modules/ is gitignored and not copied by
release.yaml, so a phantom "HelloWorld: true" status is ignored by nwidart (no
such module on disk). bootstrap/cache/modules.php is gitignored (absent in CI),
so nothing overrides the committed file.
Verified with `php artisan test --filter=HelloWorld` (the CI command) and the
full suite: 462 pass; pint clean.
* fix(test): commit the Modules/HelloWorld sample module
HelloWorldIntegrationTest exercises Modules/HelloWorld end-to-end, but Modules/
was gitignored (/Modules), so the module was absent from the repo and from CI —
the 5 integration tests 404'd, and the committed modules_statuses.json merely
enabled a module that wasn't there.
Track Modules/HelloWorld (the test fixture) via a `/Modules/*` + `!HelloWorld`
negation. Not shipped to prod (release.yaml omits Modules/). Now the module is
present, autoloaded (merge-plugin), and enabled (statuses file), so its provider
boots and the menu/settings/routes register.
* build: drop the boost:update post-update-cmd hook (breaks CI)
laravel/boost gates its commands to the local environment, so `php artisan
boost:update` fails in CI ("There are no commands defined in the boost
namespace"), making composer's post-update-cmd return exit 1.
It only began failing the build once Modules/HelloWorld/composer.json was
committed: the wikimedia merge-plugin then runs composer's update path on a
plain `composer install`, triggering post-update-cmd. Drop the auto-update
hook (run `boost:update` manually when needed); vendor:publish stays.
70 lines
1.8 KiB
JavaScript
Vendored
70 lines
1.8 KiB
JavaScript
Vendored
import { defineConfig } from 'vite'
|
|
import vue from '@vitejs/plugin-vue'
|
|
import { resolve } from 'path'
|
|
|
|
/**
|
|
* Module build config.
|
|
*
|
|
* Produces a single `resources/dist/init.js` ES module that the host app
|
|
* loads via <script type="module">. Vue is externalized and resolved from
|
|
* the host's `window.__invoiceshelf_vue` global at runtime.
|
|
*
|
|
* The vueGlobalPlugin rewrites `import { ref, ... } from "vue"` into
|
|
* destructuring from the host global — no separate Vue bundle, no import
|
|
* map, and the module shares the host's Vue instance so globally
|
|
* registered Base* components are accessible via resolveComponent().
|
|
*/
|
|
|
|
/**
|
|
* Vite plugin that replaces Vue imports with the host's global at runtime.
|
|
* Works by marking 'vue' as external and then rewriting the import in the
|
|
* output via renderChunk.
|
|
*/
|
|
function vueGlobalPlugin() {
|
|
return {
|
|
name: 'invoiceshelf-vue-global',
|
|
enforce: 'pre',
|
|
resolveId(source) {
|
|
if (source === 'vue') {
|
|
return { id: 'vue', external: true }
|
|
}
|
|
},
|
|
renderChunk(code) {
|
|
// Replace: import { ref, computed, ... } from "vue";
|
|
// With: const { ref, computed, ... } = window.__invoiceshelf_vue;
|
|
return code.replace(
|
|
/import\s*(\{[^}]+\})\s*from\s*"vue"\s*;?/g,
|
|
'const $1 = window.__invoiceshelf_vue;'
|
|
)
|
|
},
|
|
}
|
|
}
|
|
|
|
export default defineConfig({
|
|
build: {
|
|
outDir: resolve(__dirname, 'resources/dist'),
|
|
emptyOutDir: true,
|
|
lib: {
|
|
entry: resolve(__dirname, 'resources/js/init.ts'),
|
|
formats: ['es'],
|
|
fileName: () => 'init.js',
|
|
},
|
|
},
|
|
plugins: [
|
|
vueGlobalPlugin(),
|
|
vue({
|
|
template: {
|
|
transformAssetUrls: {
|
|
base: null,
|
|
includeAbsolute: false,
|
|
},
|
|
},
|
|
}),
|
|
],
|
|
resolve: {
|
|
alias: {
|
|
'@': resolve(__dirname, 'resources/js'),
|
|
},
|
|
},
|
|
})
|