@ossy/app 3.17.0 → 3.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/build.task.js +12 -12
- package/cli/manifest-plugin.js +34 -1
- package/package.json +13 -13
- package/src/shell/AppSettings.jsx +5 -0
- package/src/shell/WorkspaceAppSettingsSync.jsx +14 -0
package/cli/build.task.js
CHANGED
|
@@ -64,24 +64,24 @@ function ensureDir (dir) {
|
|
|
64
64
|
/**
|
|
65
65
|
* Copy heavy optional browser deps that feature packages load via non-literal
|
|
66
66
|
* `import()` so Rollup never opens them (CI OOM). `@ossy/resumes` Word export
|
|
67
|
-
* loads `/static/vendor/docx.mjs
|
|
67
|
+
* loads `/static/vendor/docx.mjs`. Skip quietly when not installed.
|
|
68
68
|
*
|
|
69
69
|
* @param {string} staticOutDir
|
|
70
70
|
* @param {string} projectRoot
|
|
71
71
|
*/
|
|
72
|
-
function copyExternalBrowserVendors (staticOutDir, projectRoot) {
|
|
73
|
-
|
|
72
|
+
async function copyExternalBrowserVendors (staticOutDir, projectRoot) {
|
|
73
|
+
const requireFromRoot = createRequire(path.join(projectRoot, 'package.json'))
|
|
74
|
+
const destDir = path.join(staticOutDir, 'vendor')
|
|
75
|
+
ensureDir(destDir)
|
|
76
|
+
|
|
74
77
|
try {
|
|
75
|
-
docxEntry =
|
|
78
|
+
const docxEntry = requireFromRoot.resolve('docx')
|
|
79
|
+
// `docx` resolves to dist/index.cjs; ship the self-contained ESM build for browsers.
|
|
80
|
+
const src = path.join(path.dirname(docxEntry), 'index.mjs')
|
|
81
|
+
if (fs.existsSync(src)) fs.copyFileSync(src, path.join(destDir, 'docx.mjs'))
|
|
76
82
|
} catch {
|
|
77
|
-
|
|
83
|
+
// optional
|
|
78
84
|
}
|
|
79
|
-
// `docx` resolves to dist/index.cjs; ship the self-contained ESM build for browsers.
|
|
80
|
-
const src = path.join(path.dirname(docxEntry), 'index.mjs')
|
|
81
|
-
if (!fs.existsSync(src)) return
|
|
82
|
-
const destDir = path.join(staticOutDir, 'vendor')
|
|
83
|
-
ensureDir(destDir)
|
|
84
|
-
fs.copyFileSync(src, path.join(destDir, 'docx.mjs'))
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
// One source of truth for the per-entry name. Used both as the Rollup
|
|
@@ -489,7 +489,7 @@ export async function build (cliArgs = []) {
|
|
|
489
489
|
|
|
490
490
|
await bundle.close()
|
|
491
491
|
|
|
492
|
-
copyExternalBrowserVendors(staticOutDir, cwd)
|
|
492
|
+
await copyExternalBrowserVendors(staticOutDir, cwd)
|
|
493
493
|
|
|
494
494
|
if (fs.existsSync(publicSrc)) {
|
|
495
495
|
fs.cpSync(publicSrc, publicOutDir, { recursive: true, force: true })
|
package/cli/manifest-plugin.js
CHANGED
|
@@ -609,7 +609,28 @@ export function manifestPlugin ({ entriesByStub, srcDir, staticOutDir, configVal
|
|
|
609
609
|
'Assign components to app slots in `*.layout.jsx` via `export const slots`.',
|
|
610
610
|
)
|
|
611
611
|
}
|
|
612
|
-
|
|
612
|
+
/** @type {Record<string, unknown>} */
|
|
613
|
+
const componentEntry = {
|
|
614
|
+
id,
|
|
615
|
+
entry: url,
|
|
616
|
+
package: entryPackage(entryInfo, appPackageName),
|
|
617
|
+
}
|
|
618
|
+
const widget = rawMeta.widget
|
|
619
|
+
if (widget && typeof widget === 'object' && !Array.isArray(widget)) {
|
|
620
|
+
const title = typeof widget.title === 'string'
|
|
621
|
+
? widget.title.trim()
|
|
622
|
+
: ''
|
|
623
|
+
const description = typeof widget.description === 'string'
|
|
624
|
+
? widget.description.trim()
|
|
625
|
+
: ''
|
|
626
|
+
if (title) {
|
|
627
|
+
componentEntry.widget = {
|
|
628
|
+
title,
|
|
629
|
+
...(description ? { description } : {}),
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
components.push(withSourcePath(componentEntry, entryInfo, projectRoot))
|
|
613
634
|
continue
|
|
614
635
|
}
|
|
615
636
|
|
|
@@ -780,6 +801,17 @@ export function manifestPlugin ({ entriesByStub, srcDir, staticOutDir, configVal
|
|
|
780
801
|
}
|
|
781
802
|
}
|
|
782
803
|
|
|
804
|
+
const widgets = components
|
|
805
|
+
.filter((component) => component?.widget?.title)
|
|
806
|
+
.map((component) => ({
|
|
807
|
+
componentId: component.id,
|
|
808
|
+
title: component.widget.title,
|
|
809
|
+
...(component.widget.description
|
|
810
|
+
? { description: component.widget.description }
|
|
811
|
+
: {}),
|
|
812
|
+
...(component.package ? { package: component.package } : {}),
|
|
813
|
+
}))
|
|
814
|
+
|
|
783
815
|
const manifest = {
|
|
784
816
|
entries,
|
|
785
817
|
components,
|
|
@@ -798,6 +830,7 @@ export function manifestPlugin ({ entriesByStub, srcDir, staticOutDir, configVal
|
|
|
798
830
|
actionRoutes,
|
|
799
831
|
taskCatalog,
|
|
800
832
|
taskGraphEdges,
|
|
833
|
+
widgets,
|
|
801
834
|
}
|
|
802
835
|
fs.mkdirSync(path.dirname(manifestPath), { recursive: true })
|
|
803
836
|
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), 'utf8')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ossy/app",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.19.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"source": "./src/index.js",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -50,21 +50,21 @@
|
|
|
50
50
|
"@babel/preset-react": "^7.26.3",
|
|
51
51
|
"@babel/register": "^7.25.9",
|
|
52
52
|
"@ossy/authentication": "^3.11.1",
|
|
53
|
-
"@ossy/design-system": "^3.
|
|
53
|
+
"@ossy/design-system": "^3.19.0",
|
|
54
54
|
"@ossy/locale": "^3.4.0",
|
|
55
|
-
"@ossy/manifest": "^3.
|
|
56
|
-
"@ossy/package-catalog": "^3.
|
|
55
|
+
"@ossy/manifest": "^3.18.0",
|
|
56
|
+
"@ossy/package-catalog": "^3.19.0",
|
|
57
57
|
"@ossy/pages": "^3.0.9",
|
|
58
|
-
"@ossy/platform": "^3.
|
|
59
|
-
"@ossy/resources": "^3.
|
|
58
|
+
"@ossy/platform": "^3.19.0",
|
|
59
|
+
"@ossy/resources": "^3.19.0",
|
|
60
60
|
"@ossy/router": "^3.0.9",
|
|
61
|
-
"@ossy/router-react": "^3.
|
|
62
|
-
"@ossy/schema": "^3.
|
|
63
|
-
"@ossy/sdk": "^3.
|
|
61
|
+
"@ossy/router-react": "^3.18.0",
|
|
62
|
+
"@ossy/schema": "^3.18.0",
|
|
63
|
+
"@ossy/sdk": "^3.18.0",
|
|
64
64
|
"@ossy/sdk-react": "^3.12.0",
|
|
65
|
-
"@ossy/themes": "^3.
|
|
66
|
-
"@ossy/users": "^3.
|
|
67
|
-
"@ossy/workspaces": "^3.
|
|
65
|
+
"@ossy/themes": "^3.18.0",
|
|
66
|
+
"@ossy/users": "^3.18.0",
|
|
67
|
+
"@ossy/workspaces": "^3.18.0",
|
|
68
68
|
"@rollup/plugin-alias": "^6.0.0",
|
|
69
69
|
"@rollup/plugin-babel": "^7.1.0",
|
|
70
70
|
"@rollup/plugin-commonjs": "^29.0.0",
|
|
@@ -98,5 +98,5 @@
|
|
|
98
98
|
"README.md",
|
|
99
99
|
"tsconfig.json"
|
|
100
100
|
],
|
|
101
|
-
"gitHead": "
|
|
101
|
+
"gitHead": "0ac103001a468f56597c02cf1c6802bf7bd89b33"
|
|
102
102
|
}
|
|
@@ -46,6 +46,11 @@ export function defaultAppSettings() {
|
|
|
46
46
|
/** Task catalog from `app build` (ADR 0011) — for automation topology UI. */
|
|
47
47
|
taskCatalog: undefined,
|
|
48
48
|
taskGraphEdges: undefined,
|
|
49
|
+
/**
|
|
50
|
+
* Dashboard pin catalog from `app build` — components that export
|
|
51
|
+
* `metadata.widget` (any package can register).
|
|
52
|
+
*/
|
|
53
|
+
widgets: undefined,
|
|
49
54
|
/** Action id → HTTP route map for sdk.invoke transport routing. */
|
|
50
55
|
actionRoutes: undefined,
|
|
51
56
|
/**
|
|
@@ -17,6 +17,10 @@ function buildPatch (workspace, workspaces) {
|
|
|
17
17
|
* Persists workspace shell snapshot to the signed user-app-settings cookie
|
|
18
18
|
* (via ProxyInternal PATCH /@ossy/users/me/app-settings) so SSR bootstrap
|
|
19
19
|
* props stay stable across full-page navigations.
|
|
20
|
+
*
|
|
21
|
+
* Also keeps `sdk.workspaceId` in sync so workspace-scoped action invocations
|
|
22
|
+
* include the workspaceId header even when it was absent from the initial SSR
|
|
23
|
+
* bootstrap props.
|
|
20
24
|
*/
|
|
21
25
|
export function WorkspaceAppSettingsSync () {
|
|
22
26
|
const sdk = useSdk()
|
|
@@ -24,6 +28,16 @@ export function WorkspaceAppSettingsSync () {
|
|
|
24
28
|
const { data: workspaces } = sdk.read(ListWorkspaces)
|
|
25
29
|
const lastPatchRef = useRef('')
|
|
26
30
|
|
|
31
|
+
// Keep sdk.workspaceId in sync with the live workspace read so that
|
|
32
|
+
// sdk.invoke sends the workspaceId header for workspace-scoped actions.
|
|
33
|
+
// useSdk() returns a wrapper object; the underlying ReactSdk is at .sdk.
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
const reactSdk = sdk.sdk
|
|
36
|
+
if (workspace?.id && reactSdk?.workspaceId !== workspace.id) {
|
|
37
|
+
reactSdk?.updateConfig({ workspaceId: workspace.id })
|
|
38
|
+
}
|
|
39
|
+
}, [workspace?.id, sdk])
|
|
40
|
+
|
|
27
41
|
useEffect(() => {
|
|
28
42
|
const patch = buildPatch(workspace, workspaces)
|
|
29
43
|
if (!patch) return
|