Commit cff4fe0
committed
feat(integrations): artifact-based community installs with import-map runtime
Make community integrations installable in production without rebuilding or
touching the app-api image. Installs land in a bind-mounted
`custom_integrations/` so they survive container replacement; backend code
loads from `dist/backend/index.mjs`, frontend from `dist/frontend/index.js`.
The api never builds, never `pnpm install`s, never imports plugin tooling.
Admin install = artifact only
Two payload shapes on POST /admin/store/install:
{ repository } catalog entry (artifact.url required)
{ artifactUrl, sha256?, version? } manual install
Source installs from git remain a CLI-only developer workflow. The
Install-from-URL dialog drops the Source/Artifact toggle in favour of a
single artifact URL + optional sha256 form. Updates require the integration
to be catalog-managed (sourceType=registry + repository match) so we always
have a fresh artifact URL to install from; `canUpdateFromCatalog` is the
single helper used by the listing badge, the install endpoint, and the
store service.
Drops `OPENMAPX_INTEGRATION_BUILDER_IMAGE` entirely (admin install never
needs Docker-in-Docker to build) and drops the `git` value from the
`source_type` enum — only `registry | artifact` now.
CLI build path
`pnpm openmapx integrations install ./src` and `... package <src> --out
file.tar.gz` both bundle with esbuild's JS API (`import("esbuild")`), so
the build only ever runs in the process that has esbuild installed. The
installer surfaces a clear error if a non-CLI consumer asks for a build.
Drops the `findEsbuildBinary` lookup-on-disk path, the NODE_PATH
reconstruction, the `--builder-image` flag on every command, and the
`validateCommunitySourceBoundary` regex check — esbuild's externals/aliases
are the contract; disallowed imports fail at bundle time.
Artifact contract
Tarball ships:
manifest.json
dist/frontend/index.js when frontend components are declared
dist/backend/index.mjs when backend code is present
openmapx-artifact.json platform version + per-bundle sha256
strings/<locale>.json optional
Explicitly forbidden: node_modules/. Bundles must be self-contained.
Manifest drops `npmDependencies`, `frontendDependencies`, and
`runtimeDependencies`. Tar extraction keeps the existing zip-slip,
symlink/hardlink, and PAX-escape guards.
Frontend runtime singletons via import maps
Replaces the regex-scraped `window.__openmapx_runtime` shim system with a
native `<script type="importmap">` in apps/web/src/app/layout.tsx that
points `react`, `react/jsx-runtime`, `react/jsx-dev-runtime`, and
`@openmapx/core` at prebuilt ESM files under apps/web/public/runtime/.
The new apps/web/scripts/build-runtime-modules.mjs runs in `predev` and
`prebuild` to emit those files via esbuild. Integration bundles keep bare
`import React from "react"` as externals; the browser resolves them at
runtime, so React + @openmapx/core stay strict singletons across every
loaded community bundle and adding a new core export "just works" without
re-packaging artifacts.
Drops `coreRuntimeExportNames`, `REACT_RUNTIME_EXPORTS`,
`CORE_RUNTIME_EXPORT_FALLBACKS`, `writeRuntimeShims`, and the
`window.__openmapx_runtime` wiring in IntegrationProvider.
Backend reload semantics
In dev (`NODE_ENV !== "production"`), backend module URLs are still
mtime-busted so /api/integrations/reload picks up in-place edits. In prod
the URL is *not* cache-busted — Node's ESM loader returns the cached
module without leaking memory, so updates to an already-loaded integration
need `pnpm openmapx services restart app-api`. The install/update job logs
surface that hint automatically. New installs work without restart.
Replaces the per-route Fastify registration with a single mini-dispatcher
+ sorted route table so reload genuinely replaces the route map. Pattern
subset documented inline: literal segments, `:param`, and a trailing `*`.
Tests + typecheck
Updates packages/cli/__tests__/cli-integrations.test.ts to match the new
contract (asserts bare-spec externals in the bundle, rejects artifacts
shipping node_modules/, drops the deprecated-deps tests). All passing:
packages/cli 129, packages/core 284, apps/api 1069 (+4 skipped).1 parent 2d54818 commit cff4fe0
33 files changed
Lines changed: 2105 additions & 322 deletions
File tree
- apps
- api
- src
- db
- routes
- services
- web
- scripts
- src
- app
- components/admin/store
- providers
- docs
- infra/docker
- packages
- cli
- __tests__
- src/commands
- core
- src
- integration
- services
- app-api
- data-manager
- motis/tools/transitous
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
4 | 7 | | |
5 | 8 | | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
6 | 12 | | |
7 | 13 | | |
8 | 14 | | |
9 | 15 | | |
10 | 16 | | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
11 | 25 | | |
12 | | - | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
13 | 40 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
| 15 | + | |
14 | 16 | | |
15 | 17 | | |
16 | 18 | | |
17 | 19 | | |
| 20 | + | |
18 | 21 | | |
19 | 22 | | |
20 | 23 | | |
| |||
35 | 38 | | |
36 | 39 | | |
37 | 40 | | |
| 41 | + | |
38 | 42 | | |
39 | 43 | | |
40 | 44 | | |
41 | 45 | | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
42 | 49 | | |
43 | 50 | | |
44 | 51 | | |
| |||
54 | 61 | | |
55 | 62 | | |
56 | 63 | | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
57 | 67 | | |
58 | 68 | | |
59 | 69 | | |
| |||
67 | 77 | | |
68 | 78 | | |
69 | 79 | | |
| 80 | + | |
70 | 81 | | |
This file was deleted.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
| 11 | + | |
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| |||
120 | 120 | | |
121 | 121 | | |
122 | 122 | | |
123 | | - | |
| 123 | + | |
124 | 124 | | |
125 | 125 | | |
126 | 126 | | |
| |||
151 | 151 | | |
152 | 152 | | |
153 | 153 | | |
154 | | - | |
| 154 | + | |
155 | 155 | | |
156 | 156 | | |
157 | 157 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
| 10 | + | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
24 | | - | |
| 24 | + | |
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
| |||
63 | 63 | | |
64 | 64 | | |
65 | 65 | | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
66 | 70 | | |
67 | 71 | | |
68 | 72 | | |
69 | 73 | | |
70 | 74 | | |
71 | 75 | | |
72 | 76 | | |
73 | | - | |
| 77 | + | |
74 | 78 | | |
75 | 79 | | |
76 | 80 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
| 10 | + | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| |||
0 commit comments