@multiplatform.one/cli 6.4.3 → 6.7.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/README.md +23 -1
- package/lib/bin/multiplatformOne.mjs +5 -3
- package/lib/commands/initApp.mjs +209 -8
- package/lib/commands/updateApp.mjs +170 -16
- package/package.json +3 -3
- package/src/bin/multiplatformOne.ts +14 -1
- package/src/commands/initApp.spec.ts +369 -3
- package/src/commands/initApp.ts +324 -4
- package/src/commands/updateApp.spec.ts +81 -0
- package/src/commands/updateApp.ts +212 -6
- package/templates/app/apps/__NAME__/package.json +2 -1
- package/templates/app/features/__NAME__/package.json +1 -1
- package/templates/app/packages/config/package.json +1 -1
- package/templates/pieces/frappe/universal/README.md.partial +32 -0
- package/templates/pieces/frappe/universal/docker/compose.frappe.yaml +52 -0
- package/templates/pieces/frappe/universal/env.example.partial +8 -0
- package/templates/pieces/frappe/universal/packages/config/config.json.partial +3 -0
- package/templates/pieces/gnome/universal/README.md.partial +68 -0
- package/templates/pieces/gnome/universal/apps/__NAME__/gnome/main.tsx +165 -0
- package/templates/pieces/gnome/universal/apps/__NAME__/gnome/polyfills.ts +10 -0
- package/templates/pieces/gnome/universal/apps/__NAME__/gnome/shims/components.ts +36 -0
- package/templates/pieces/gnome/universal/apps/__NAME__/gnome/shims/empty-module.ts +28 -0
- package/templates/pieces/gnome/universal/apps/__NAME__/gnome/shims/forms.ts +18 -0
- package/templates/pieces/gnome/universal/apps/__NAME__/gnome/shims/one.ts +89 -0
- package/templates/pieces/gnome/universal/apps/__NAME__/gnome/shims/theme.ts +25 -0
- package/templates/pieces/gnome/universal/apps/__NAME__/gnome/tamagui-barrel.ts +77 -0
- package/templates/pieces/gnome/universal/apps/__NAME__/package.json.partial +18 -0
- package/templates/pieces/gnome/universal/apps/__NAME__/vite.config.gnome.ts +124 -0
- package/templates/pieces/gnome/universal/gitignore.partial +3 -0
- package/templates/pieces/gnome/universal/package.json.partial +6 -0
- package/templates/pieces/keycloak/universal/README.md.partial +19 -0
- package/templates/pieces/keycloak/universal/docker/compose.keycloak.yaml +27 -0
- package/templates/pieces/keycloak/universal/docker/keycloak/realm.json +43 -0
- package/templates/pieces/keycloak/universal/env.example.partial +9 -0
- package/templates/pieces/keycloak/universal/packages/config/config.json.partial +9 -0
- package/templates/pieces/tauri/universal/README.md.partial +18 -0
- package/templates/pieces/tauri/universal/apps/__NAME__/package.json.partial +10 -0
- package/templates/pieces/tauri/universal/apps/__NAME__/src-tauri/Cargo.toml +26 -0
- package/templates/pieces/tauri/universal/apps/__NAME__/src-tauri/build.rs +3 -0
- package/templates/pieces/tauri/universal/apps/__NAME__/src-tauri/capabilities/default.json +7 -0
- package/templates/pieces/tauri/universal/apps/__NAME__/src-tauri/icons/128x128.png +0 -0
- package/templates/pieces/tauri/universal/apps/__NAME__/src-tauri/icons/128x128@2x.png +0 -0
- package/templates/pieces/tauri/universal/apps/__NAME__/src-tauri/icons/32x32.png +0 -0
- package/templates/pieces/tauri/universal/apps/__NAME__/src-tauri/icons/icon.icns +0 -0
- package/templates/pieces/tauri/universal/apps/__NAME__/src-tauri/icons/icon.ico +0 -0
- package/templates/pieces/tauri/universal/apps/__NAME__/src-tauri/src/lib.rs +14 -0
- package/templates/pieces/tauri/universal/apps/__NAME__/src-tauri/src/main.rs +9 -0
- package/templates/pieces/tauri/universal/apps/__NAME__/src-tauri/tauri.conf.json +43 -0
- package/templates/pieces/tauri/universal/gitignore.partial +3 -0
- package/templates/pieces/tauri/universal/package.json.partial +6 -0
- package/templates/pieces/vscode/universal/README.md.partial +17 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/package.json.partial +19 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vite.config.vscode.ts +17 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vscode/extension/env.d.ts +1 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vscode/extension/index.ts +13 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vscode/extension/views/helper.ts +14 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vscode/extension/views/panel.ts +38 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vscode/index.html +49 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vscode/manifest.ts +33 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vscode/package.json +7 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vscode/tamagui.css +3 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vscode/tsconfig.json +9 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vscode/webview/app.tsx +24 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vscode/webview/components/ErrorBoundary.tsx +41 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vscode/webview/fonts/inter-400.woff2 +0 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vscode/webview/fonts/inter-700.woff2 +0 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vscode/webview/fonts.css +21 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vscode/webview/main.tsx +35 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vscode/webview/router.tsx +58 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vscode/webview/useVSCodeTheme.ts +56 -0
- package/templates/pieces/vscode/universal/apps/__NAME__/vscode/webview/utils/vscode.ts +16 -0
- package/templates/pieces/vscode/universal/gitignore.partial +2 -0
- package/templates/pieces/vscode/universal/package.json.partial +6 -0
- package/templates/pieces/webext/universal/README.md.partial +16 -0
- package/templates/pieces/webext/universal/apps/__NAME__/package.json.partial +22 -0
- package/templates/pieces/webext/universal/apps/__NAME__/tsconfig.json.partial +5 -0
- package/templates/pieces/webext/universal/apps/__NAME__/vite.config.webext-background.ts +19 -0
- package/templates/pieces/webext/universal/apps/__NAME__/vite.config.webext.ts +35 -0
- package/templates/pieces/webext/universal/apps/__NAME__/webext/assets/fonts/inter-400.woff2 +0 -0
- package/templates/pieces/webext/universal/apps/__NAME__/webext/assets/fonts/inter-700.woff2 +0 -0
- package/templates/pieces/webext/universal/apps/__NAME__/webext/background/main.ts +10 -0
- package/templates/pieces/webext/universal/apps/__NAME__/webext/components/ErrorBoundary.tsx +41 -0
- package/templates/pieces/webext/universal/apps/__NAME__/webext/env.ts +2 -0
- package/templates/pieces/webext/universal/apps/__NAME__/webext/manifest.ts +45 -0
- package/templates/pieces/webext/universal/apps/__NAME__/webext/prepare.ts +21 -0
- package/templates/pieces/webext/universal/apps/__NAME__/webext/static/assets/icon-512.png +0 -0
- package/templates/pieces/webext/universal/apps/__NAME__/webext/tamagui.css +3 -0
- package/templates/pieces/webext/universal/apps/__NAME__/webext/tsconfig.json +9 -0
- package/templates/pieces/webext/universal/apps/__NAME__/webext/views/popup/index.html +77 -0
- package/templates/pieces/webext/universal/apps/__NAME__/webext/views/popup/main.tsx +73 -0
- package/templates/pieces/webext/universal/gitignore.partial +2 -0
- package/templates/pieces/webext/universal/package.json.partial +6 -0
- package/templates/universal/apps/__NAME__/package.json +2 -1
- package/templates/universal/features/__NAME__/package.json +1 -1
- package/templates/universal/packages/config/package.json +1 -1
- package/templates/universal/packages/i18n/package.json +1 -1
- package/templates/universal/packages/themes/package.json +1 -1
- package/types/commands/initApp.d.ts +43 -0
- package/types/commands/initApp.d.ts.map +1 -1
- package/types/commands/updateApp.d.ts +4 -0
- package/types/commands/updateApp.d.ts.map +1 -1
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Vite config for the webext views target (the popup extension page) — one
|
|
2
|
+
// of two builds staging the loadable MV3 extension into dist-webext (see
|
|
3
|
+
// also vite.config.webext-background.ts; webext/prepare.ts writes the
|
|
4
|
+
// manifest + static assets). The shared machinery (workspace source
|
|
5
|
+
// aliases, Tamagui wiring, MV3 staging layout) lives in
|
|
6
|
+
// @multiplatform.one/vite-plugin-webext.
|
|
7
|
+
|
|
8
|
+
import { resolve } from "node:path";
|
|
9
|
+
import { resolveConfig } from "@multiplatform.one/utils/dev";
|
|
10
|
+
import { createWebextViewsConfig } from "@multiplatform.one/vite-plugin-webext";
|
|
11
|
+
import dotenv from "dotenv";
|
|
12
|
+
import { defineConfig } from "vite";
|
|
13
|
+
import { public as publicConfigKeys } from "../../packages/config/config.json";
|
|
14
|
+
import packageJson from "./package.json";
|
|
15
|
+
import { isDev, port } from "./webext/env";
|
|
16
|
+
|
|
17
|
+
dotenv.config({ path: resolve(import.meta.dirname, "../../.env") });
|
|
18
|
+
process.env.VITE_MP_CONFIG = JSON.stringify(resolveConfig(publicConfigKeys));
|
|
19
|
+
|
|
20
|
+
export default defineConfig(async () =>
|
|
21
|
+
createWebextViewsConfig({
|
|
22
|
+
targetDir: resolve(import.meta.dirname, "webext"),
|
|
23
|
+
stagingDir: resolve(import.meta.dirname, "dist-webext"),
|
|
24
|
+
tamaguiConfig: resolve(import.meta.dirname, "config/tamagui.config.ts"),
|
|
25
|
+
packageInfo: packageJson,
|
|
26
|
+
isDev,
|
|
27
|
+
port,
|
|
28
|
+
aliases: [
|
|
29
|
+
// One routing layer: extension pages have no One server runtime — the
|
|
30
|
+
// `one` import surface rides the stack-navigation seam instead (the
|
|
31
|
+
// same DOM page stack the VS Code webview target uses).
|
|
32
|
+
{ find: /^one$/, replacement: "@multiplatform.one/router/seam" },
|
|
33
|
+
],
|
|
34
|
+
}),
|
|
35
|
+
);
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// MV3 background entry (service worker on chromium, background script on
|
|
2
|
+
// firefox) — built as a single-file iife by vite.config.webext-background.ts.
|
|
3
|
+
// Extend with runtime messaging / alarms / context menus as the extension
|
|
4
|
+
// grows; dev mode reloads it on rebuild when the extension is reloaded.
|
|
5
|
+
|
|
6
|
+
import browser from "webextension-polyfill";
|
|
7
|
+
|
|
8
|
+
browser.runtime.onInstalled.addListener(() => {
|
|
9
|
+
console.info("__NAME__ extension installed");
|
|
10
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Component, type ErrorInfo, type ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Plain-DOM error boundary: it must render without Tamagui so a failure
|
|
5
|
+
* inside the provider stack itself still surfaces a readable error instead
|
|
6
|
+
* of a blank extension page.
|
|
7
|
+
*/
|
|
8
|
+
export class ErrorBoundary extends Component<
|
|
9
|
+
{ children: ReactNode },
|
|
10
|
+
{ hasError: boolean; error: Error | null; errorInfo: ErrorInfo | null }
|
|
11
|
+
> {
|
|
12
|
+
constructor(props: { children: ReactNode }) {
|
|
13
|
+
super(props);
|
|
14
|
+
this.state = { hasError: false, error: null, errorInfo: null };
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static getDerivedStateFromError(error: Error) {
|
|
18
|
+
return { hasError: true, error };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
|
22
|
+
this.setState({ error, errorInfo });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
render() {
|
|
26
|
+
if (this.state.hasError) {
|
|
27
|
+
return (
|
|
28
|
+
<div style={{ padding: 16, color: "red" }}>
|
|
29
|
+
<h2>Something went wrong</h2>
|
|
30
|
+
<details style={{ whiteSpace: "pre-wrap", marginTop: 16 }}>
|
|
31
|
+
<summary>Error Details</summary>
|
|
32
|
+
{this.state.error?.toString()}
|
|
33
|
+
<br />
|
|
34
|
+
{this.state.errorInfo?.componentStack}
|
|
35
|
+
</details>
|
|
36
|
+
</div>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
return this.props.children;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { isFirefoxExtension } from "@multiplatform.one/platform";
|
|
4
|
+
import type { Manifest } from "webextension-polyfill";
|
|
5
|
+
import { isDev, port } from "./env";
|
|
6
|
+
|
|
7
|
+
/** Extension display identity — the app's package.json name (@app/__NAME__)
|
|
8
|
+
* is the workspace manifest, not a user-facing extension name. */
|
|
9
|
+
const DISPLAY_NAME = "__NAME_PASCAL__";
|
|
10
|
+
|
|
11
|
+
export async function getManifest() {
|
|
12
|
+
const pkg = JSON.parse(
|
|
13
|
+
await fs.promises.readFile(path.resolve(import.meta.dirname, "../package.json"), "utf-8"),
|
|
14
|
+
) as { version?: string; description?: string };
|
|
15
|
+
const manifest: Manifest.WebExtensionManifest = {
|
|
16
|
+
manifest_version: 3,
|
|
17
|
+
name: DISPLAY_NAME,
|
|
18
|
+
version: pkg.version || "0.0.0",
|
|
19
|
+
description: pkg.description,
|
|
20
|
+
action: {
|
|
21
|
+
default_icon: "./assets/icon-512.png",
|
|
22
|
+
default_popup: "./dist/views/popup/index.html",
|
|
23
|
+
},
|
|
24
|
+
background: isFirefoxExtension
|
|
25
|
+
? {
|
|
26
|
+
scripts: ["./dist/background/index.mjs"],
|
|
27
|
+
type: "module",
|
|
28
|
+
}
|
|
29
|
+
: {
|
|
30
|
+
service_worker: "./dist/background/index.mjs",
|
|
31
|
+
},
|
|
32
|
+
icons: {
|
|
33
|
+
16: "./assets/icon-512.png",
|
|
34
|
+
48: "./assets/icon-512.png",
|
|
35
|
+
128: "./assets/icon-512.png",
|
|
36
|
+
},
|
|
37
|
+
permissions: ["storage", "activeTab"],
|
|
38
|
+
content_security_policy: {
|
|
39
|
+
extension_pages: isDev
|
|
40
|
+
? `script-src 'self' http://localhost:${port}; connect-src 'self' ws://localhost:${port} http://localhost:${port}; object-src 'self'`
|
|
41
|
+
: "script-src 'self'; object-src 'self'",
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
return manifest;
|
|
45
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Stage the loadable extension (manifest + icons + dev HMR scaffolding)
|
|
2
|
+
// into dist-webext. The pipeline lives in
|
|
3
|
+
// @multiplatform.one/vite-plugin-webext; this file only supplies the
|
|
4
|
+
// app-owned manifest.
|
|
5
|
+
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { runWebextPrepare } from "@multiplatform.one/vite-plugin-webext";
|
|
8
|
+
import { isDev, port } from "./env";
|
|
9
|
+
import { getManifest } from "./manifest";
|
|
10
|
+
|
|
11
|
+
runWebextPrepare({
|
|
12
|
+
targetDir: import.meta.dirname,
|
|
13
|
+
stagingDir: path.resolve(import.meta.dirname, "../dist-webext"),
|
|
14
|
+
getManifest,
|
|
15
|
+
isDev,
|
|
16
|
+
port,
|
|
17
|
+
watch: isDev,
|
|
18
|
+
}).catch((err) => {
|
|
19
|
+
console.error(err);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
});
|
|
Binary file
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>__NAME_PASCAL__</title>
|
|
7
|
+
<!--
|
|
8
|
+
Popup frame + mount sizing. A popup has no viewport of its own to
|
|
9
|
+
inherit, so the frame is pinned here rather than from JS: first paint
|
|
10
|
+
already has it. #app MUST end up with a definite height — the screens
|
|
11
|
+
render inside DomNavigationHost, which fills its parent, and a parent
|
|
12
|
+
with no height paints nothing however complete the DOM looks.
|
|
13
|
+
-->
|
|
14
|
+
<style>
|
|
15
|
+
* {
|
|
16
|
+
box-sizing: border-box;
|
|
17
|
+
}
|
|
18
|
+
html {
|
|
19
|
+
width: 400px;
|
|
20
|
+
}
|
|
21
|
+
body {
|
|
22
|
+
margin: 0;
|
|
23
|
+
padding: 0;
|
|
24
|
+
display: flex;
|
|
25
|
+
flex-direction: column;
|
|
26
|
+
min-width: 100%;
|
|
27
|
+
min-height: 500px;
|
|
28
|
+
}
|
|
29
|
+
#app {
|
|
30
|
+
display: flex;
|
|
31
|
+
flex-direction: column;
|
|
32
|
+
flex: 1 0 auto;
|
|
33
|
+
min-height: 500px;
|
|
34
|
+
}
|
|
35
|
+
</style>
|
|
36
|
+
<!--
|
|
37
|
+
Font-stable mount (LC-33): the shell owns Inter. Preload + a head face
|
|
38
|
+
with font-display: optional means first paint already renders Inter and
|
|
39
|
+
the face never swaps after mount. The relative asset URLs are resolved
|
|
40
|
+
and fingerprinted by Vite at build time (packaged with the extension).
|
|
41
|
+
-->
|
|
42
|
+
<link
|
|
43
|
+
rel="preload"
|
|
44
|
+
href="../../assets/fonts/inter-400.woff2"
|
|
45
|
+
as="font"
|
|
46
|
+
type="font/woff2"
|
|
47
|
+
crossorigin
|
|
48
|
+
/>
|
|
49
|
+
<link
|
|
50
|
+
rel="preload"
|
|
51
|
+
href="../../assets/fonts/inter-700.woff2"
|
|
52
|
+
as="font"
|
|
53
|
+
type="font/woff2"
|
|
54
|
+
crossorigin
|
|
55
|
+
/>
|
|
56
|
+
<style data-font-inter>
|
|
57
|
+
@font-face {
|
|
58
|
+
font-family: "Inter";
|
|
59
|
+
font-style: normal;
|
|
60
|
+
font-weight: 400;
|
|
61
|
+
font-display: optional;
|
|
62
|
+
src: url("../../assets/fonts/inter-400.woff2") format("woff2");
|
|
63
|
+
}
|
|
64
|
+
@font-face {
|
|
65
|
+
font-family: "Inter";
|
|
66
|
+
font-style: normal;
|
|
67
|
+
font-weight: 700;
|
|
68
|
+
font-display: optional;
|
|
69
|
+
src: url("../../assets/fonts/inter-700.woff2") format("woff2");
|
|
70
|
+
}
|
|
71
|
+
</style>
|
|
72
|
+
</head>
|
|
73
|
+
<body>
|
|
74
|
+
<div id="app"></div>
|
|
75
|
+
<script type="module" src="./main.tsx"></script>
|
|
76
|
+
</body>
|
|
77
|
+
</html>
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import "../../tamagui.css";
|
|
2
|
+
import "@tamagui/core/reset.css";
|
|
3
|
+
import { AboutScreen, AppLayout, HomeScreen } from "@features/__NAME__";
|
|
4
|
+
import { DomNavigationHost, stackNavigator } from "@multiplatform.one/router/seam";
|
|
5
|
+
import {
|
|
6
|
+
createI18nConfig,
|
|
7
|
+
defaultLanguage,
|
|
8
|
+
defaultNamespace,
|
|
9
|
+
languages,
|
|
10
|
+
namespaces,
|
|
11
|
+
} from "@package/i18n";
|
|
12
|
+
import { resources } from "@package/i18n/resources";
|
|
13
|
+
import i18next from "i18next";
|
|
14
|
+
import { StrictMode } from "react";
|
|
15
|
+
import { CookiesProvider } from "react-cookie";
|
|
16
|
+
import { createRoot } from "react-dom/client";
|
|
17
|
+
import { initReactI18next } from "react-i18next";
|
|
18
|
+
import { AppProvider } from "../../../src/app";
|
|
19
|
+
import { ErrorBoundary } from "../../components/ErrorBoundary";
|
|
20
|
+
|
|
21
|
+
// Extension pages have no One server runtime: i18n initializes synchronously
|
|
22
|
+
// from the bundled resources, and the feature screens run over the
|
|
23
|
+
// stack-navigation seam — `one` is aliased to @multiplatform.one/router/seam
|
|
24
|
+
// in vite.config.webext.ts, so useRouter/Link/usePathname keep working.
|
|
25
|
+
i18next.use(initReactI18next).init(
|
|
26
|
+
createI18nConfig({
|
|
27
|
+
languages: [...languages],
|
|
28
|
+
namespaces: [...namespaces],
|
|
29
|
+
defaultLanguage,
|
|
30
|
+
defaultNamespace,
|
|
31
|
+
resources,
|
|
32
|
+
}),
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
const ROUTES = [
|
|
36
|
+
{ pattern: "/", tag: "home", title: "Home" },
|
|
37
|
+
{ pattern: "/about", tag: "about", title: "About" },
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
stackNavigator.configure(ROUTES);
|
|
41
|
+
|
|
42
|
+
// The popup frame (400x500) and the #app mount sizing live in index.html so
|
|
43
|
+
// they apply on first paint.
|
|
44
|
+
|
|
45
|
+
function Popup() {
|
|
46
|
+
return (
|
|
47
|
+
<AppLayout>
|
|
48
|
+
<DomNavigationHost
|
|
49
|
+
routes={[
|
|
50
|
+
{ ...ROUTES[0]!, element: <HomeScreen /> },
|
|
51
|
+
{ ...ROUTES[1]!, element: <AboutScreen /> },
|
|
52
|
+
]}
|
|
53
|
+
/>
|
|
54
|
+
</AppLayout>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const container = document.getElementById("app");
|
|
59
|
+
if (container) {
|
|
60
|
+
createRoot(container).render(
|
|
61
|
+
<StrictMode>
|
|
62
|
+
<ErrorBoundary>
|
|
63
|
+
{/* Extension pages don't go through createRootLayout, which normally
|
|
64
|
+
provides cookies (ThemeProvider's useCookies throws without it). */}
|
|
65
|
+
<CookiesProvider>
|
|
66
|
+
<AppProvider>
|
|
67
|
+
<Popup />
|
|
68
|
+
</AppProvider>
|
|
69
|
+
</CookiesProvider>
|
|
70
|
+
</ErrorBoundary>
|
|
71
|
+
</StrictMode>,
|
|
72
|
+
);
|
|
73
|
+
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"dev": "one dev --port 3456",
|
|
8
8
|
"build": "one build",
|
|
9
9
|
"serve": "one serve",
|
|
10
|
-
"typecheck": "
|
|
10
|
+
"typecheck": "tsgo --noEmit",
|
|
11
11
|
"prebuild:native": "one prebuild",
|
|
12
12
|
"prebuild:ios": "one prebuild --platform ios",
|
|
13
13
|
"prebuild:android": "one prebuild --platform android",
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
"@multiplatform.one/config": "__MPO_VERSION__",
|
|
55
55
|
"@react-native-community/cli": "^20.1.3",
|
|
56
56
|
"@types/react": "~19.2.14",
|
|
57
|
+
"@typescript/native-preview": "^7.0.0-dev.20260707.2",
|
|
57
58
|
"@vitejs/plugin-react": "^6.0.2",
|
|
58
59
|
"typescript": "~5.9.3",
|
|
59
60
|
"vite": "^8.0.10"
|
|
@@ -6,6 +6,14 @@
|
|
|
6
6
|
* (apps/<name> + features/<name> + packages/config)
|
|
7
7
|
*/
|
|
8
8
|
export type InitAppTemplate = "universal" | "app";
|
|
9
|
+
/**
|
|
10
|
+
* Optional composable pieces overlaid onto the base template (additive
|
|
11
|
+
* fragments under templates/pieces/<piece>/ — the inverse of the old
|
|
12
|
+
* cookiecutter KEEP_SERVICES/KEEP_PLATFORMS removal hook). Keep sorted:
|
|
13
|
+
* pieces are recorded sorted in provenance and overlaid in this order.
|
|
14
|
+
*/
|
|
15
|
+
export declare const INIT_APP_PIECES: readonly ["frappe", "gnome", "keycloak", "tauri", "vscode", "webext"];
|
|
16
|
+
export type InitAppPiece = (typeof INIT_APP_PIECES)[number];
|
|
9
17
|
export interface InitAppOptions {
|
|
10
18
|
/** Skip pnpm install (useful for CI / dry scaffolding). */
|
|
11
19
|
skipInstall?: boolean;
|
|
@@ -17,6 +25,11 @@ export interface InitAppOptions {
|
|
|
17
25
|
template?: InitAppTemplate;
|
|
18
26
|
/** Accept defaults instead of prompting (non-interactive / CI). */
|
|
19
27
|
yes?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Composable pieces overlaid onto the base template. When omitted:
|
|
30
|
+
* checkbox prompt (interactive) or none (--yes / non-TTY).
|
|
31
|
+
*/
|
|
32
|
+
pieces?: InitAppPiece[];
|
|
20
33
|
}
|
|
21
34
|
export declare function cliVersion(): string | undefined;
|
|
22
35
|
/**
|
|
@@ -30,14 +43,44 @@ export interface MpoProvenance {
|
|
|
30
43
|
cliVersion: string;
|
|
31
44
|
name: string;
|
|
32
45
|
mpoVersion: string;
|
|
46
|
+
/** Composable pieces overlaid at init time (sorted). */
|
|
47
|
+
pieces: InitAppPiece[];
|
|
33
48
|
}
|
|
34
49
|
export declare const PROVENANCE_FILE = ".mpo.json";
|
|
35
50
|
export declare function writeProvenance(targetDir: string, provenance: MpoProvenance): void;
|
|
36
51
|
export declare function readProvenance(projectDir: string): MpoProvenance | undefined;
|
|
52
|
+
type JsonValue = string | number | boolean | null | JsonValue[] | {
|
|
53
|
+
[key: string]: JsonValue;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Deep-merge for JSON partials: objects merge recursively (fragment keys
|
|
57
|
+
* append after base keys, so e.g. package.json script order stays stable),
|
|
58
|
+
* arrays union (base order first — config.json public keys accumulate
|
|
59
|
+
* across pieces), scalars/type-mismatches take the fragment value.
|
|
60
|
+
*/
|
|
61
|
+
export declare function mergeJsonValues(base: JsonValue, fragment: JsonValue): JsonValue;
|
|
62
|
+
/**
|
|
63
|
+
* Validate + canonicalize a piece selection for a template: unknown names
|
|
64
|
+
* throw, duplicates collapse, order is always sorted (provenance and overlay
|
|
65
|
+
* order must be deterministic), and every piece must ship a fragment for the
|
|
66
|
+
* chosen template.
|
|
67
|
+
*/
|
|
68
|
+
export declare function normalizePieces(pieces: string[], template: InitAppTemplate): InitAppPiece[];
|
|
69
|
+
/** Pieces that can be offered for a template (fragment exists for it). */
|
|
70
|
+
export declare function availablePieces(template: InitAppTemplate): InitAppPiece[];
|
|
71
|
+
/**
|
|
72
|
+
* Generate apps/<name>/src/app.ts for the selected backend pieces instead of
|
|
73
|
+
* storing 2^n template variants: each selected provider adds one createApp
|
|
74
|
+
* key (frappe/keycloak read their runtime settings from the packages/config
|
|
75
|
+
* public env keys their fragments register). Only called when at least one
|
|
76
|
+
* provider piece is selected — the base template file stays otherwise.
|
|
77
|
+
*/
|
|
78
|
+
export declare function composeAppTs(pieces: InitAppPiece[]): string;
|
|
37
79
|
/**
|
|
38
80
|
* Scaffold a consumer project (universal by default, web-only with
|
|
39
81
|
* template: "app") that depends on @multiplatform.one/* at semver ranges
|
|
40
82
|
* (never workspace:*). This is NOT a monorepo fork.
|
|
41
83
|
*/
|
|
42
84
|
export declare function initApp(nameArg: string | undefined, options?: InitAppOptions): Promise<void>;
|
|
85
|
+
export {};
|
|
43
86
|
//# sourceMappingURL=initApp.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initApp.d.ts","sourceRoot":"","sources":["../../src/commands/initApp.ts"],"names":[],"mappings":"AAaA;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,KAAK,CAAC;AAElD,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,mEAAmE;IACnE,GAAG,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"initApp.d.ts","sourceRoot":"","sources":["../../src/commands/initApp.ts"],"names":[],"mappings":"AAaA;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,KAAK,CAAC;AAElD;;;;;GAKG;AACH,eAAO,MAAM,eAAe,uEAOlB,CAAC;AACX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAW5D,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2EAA2E;IAC3E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,mEAAmE;IACnE,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;;OAGG;IACH,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;CACzB;AA0CD,wBAAgB,UAAU,IAAI,MAAM,GAAG,SAAS,CAQ/C;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,eAAe,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,MAAM,EAAE,YAAY,EAAE,CAAC;CACxB;AAED,eAAO,MAAM,eAAe,cAAc,CAAC;AAE3C,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,aAAa,GAAG,IAAI,CAKlF;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAiB5E;AAiFD,KAAK,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAM/F;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,GAAG,SAAS,CAoB/E;AAoFD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,eAAe,GAAG,YAAY,EAAE,CAe3F;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,QAAQ,EAAE,eAAe,GAAG,YAAY,EAAE,CAEzE;AA2BD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,CAyC3D;AAoBD;;;;GAIG;AACH,wBAAsB,OAAO,CAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAqJf"}
|
|
@@ -20,5 +20,9 @@ export interface UpdateAppOptions {
|
|
|
20
20
|
/** Override the semver range written for @multiplatform.one/* deps. */
|
|
21
21
|
version?: string;
|
|
22
22
|
}
|
|
23
|
+
/** Structural three-way merge of package.json content. Returns the merged
|
|
24
|
+
* object, or undefined when a divergence can't be auto-resolved (the file
|
|
25
|
+
* then keeps its textual conflict markers for manual resolution). */
|
|
26
|
+
export declare function threeWayMergePackageJson(base: string | undefined, ours: string, theirs: string): Record<string, unknown> | undefined;
|
|
23
27
|
export declare function updateApp(options?: UpdateAppOptions): Promise<void>;
|
|
24
28
|
//# sourceMappingURL=updateApp.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"updateApp.d.ts","sourceRoot":"","sources":["../../src/commands/updateApp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AASH,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;
|
|
1
|
+
{"version":3,"file":"updateApp.d.ts","sourceRoot":"","sources":["../../src/commands/updateApp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AASH,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAyPD;;sEAEsE;AACtE,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAerC;AA2DD,wBAAsB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkP7E"}
|