@wix/himalaya-cli 0.1292.0 → 0.1294.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/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/webview/src/index.d.ts +35 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/webview-page/src/capabilities.generated.d.ts +88 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/_types/core/sdk/webview-page/src/index.d.ts +68 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/webview-page.mjs +88 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/dist/webview.mjs +43 -0
- package/dist/authoring-runtime/node_modules/@wix/himalaya/package.json +4 -0
- package/dist/cli.mjs +188 -65
- package/dist/preview-assets.generated.bin +0 -0
- package/guides/importable-sdks.md +1 -0
- package/guides/index.json +6 -0
- package/guides/sdk-reference.json +79 -0
- package/guides/webview-page-sdk.md +132 -0
- package/package.json +2 -2
- package/templates/beauty-salon/dev/index.ts +19 -0
- package/templates/branded-lite/dev/index.ts +19 -0
- package/templates/community-club/dev/index.ts +19 -0
- package/templates/events-meetups/dev/index.ts +19 -0
- package/templates/gym-fitness/dev/index.ts +19 -0
- package/templates/nonprofit-cause/dev/index.ts +19 -0
- package/templates/podcast-creator/dev/index.ts +19 -0
- package/templates/portfolio-creative/dev/index.ts +19 -0
- package/templates/restaurant/dev/index.ts +19 -0
- package/templates/retail-store/dev/index.ts +19 -0
- package/templates/yoga-studio/dev/index.ts +19 -0
|
Binary file
|
|
@@ -59,6 +59,7 @@ package in one greppable file) or `GET /v1/sdk/<name>` over HTTP; in the CLI,
|
|
|
59
59
|
- `@himalaya/time` — Tier-5 temporal helpers.
|
|
60
60
|
- `@himalaya/ui` — Tier-5 typed binding to the platform's imperative popup capability.
|
|
61
61
|
- `@himalaya/webview` — Tier-5 typed binding for the page ↔ worker message channel of a worker-backed webview screen (Part 2 / RFC 0025 composition).
|
|
62
|
+
- `@himalaya/webview-page` — browser-side SDK for a trusted page hosted by a worker-backed Himalaya WebView.
|
|
62
63
|
- `@himalaya/widget` — Tier-5 logic-bundle widget surface.
|
|
63
64
|
- `@himalaya/wix-llm` — narrow Tier-5 binding for Wix LLM text generation.
|
|
64
65
|
- `@himalaya/wix-platform` — Wix Platform SDK (RFC 0042), worker-facing bindings.
|
package/guides/index.json
CHANGED
|
@@ -89,6 +89,12 @@
|
|
|
89
89
|
"category": "Workers & SDKs",
|
|
90
90
|
"file": "importable-sdks.md"
|
|
91
91
|
},
|
|
92
|
+
{
|
|
93
|
+
"id": "webview-page-sdk",
|
|
94
|
+
"title": "Use native capabilities from a WebView page",
|
|
95
|
+
"category": "Workers & SDKs",
|
|
96
|
+
"file": "webview-page-sdk.md"
|
|
97
|
+
},
|
|
92
98
|
{
|
|
93
99
|
"id": "component-reference",
|
|
94
100
|
"title": "Component reference",
|
|
@@ -4073,6 +4073,85 @@
|
|
|
4073
4073
|
"jsdoc": "/**\n * Register a handler for messages the page posts via `window.HimalayaWorker.post(msg)`.\n * The latest registered handler wins. Call this once during the bundle's setup.\n */",
|
|
4074
4074
|
"decl": "export function onPageMessage(cb: (msg: unknown) => void): void;"
|
|
4075
4075
|
},
|
|
4076
|
+
{
|
|
4077
|
+
"name": "PageCapabilityRequest",
|
|
4078
|
+
"kind": "interface",
|
|
4079
|
+
"jsdoc": "",
|
|
4080
|
+
"decl": "export interface PageCapabilityRequest {\n v: 1;\n id: string;\n capability: string;\n method: string;\n args: unknown[];\n}"
|
|
4081
|
+
},
|
|
4082
|
+
{
|
|
4083
|
+
"name": "PageCapabilityResponse",
|
|
4084
|
+
"kind": "interface",
|
|
4085
|
+
"jsdoc": "",
|
|
4086
|
+
"decl": "export interface PageCapabilityResponse {\n v: 1;\n id: string;\n ok: boolean;\n result?: unknown;\n error?: { message: string; code?: string };\n}"
|
|
4087
|
+
},
|
|
4088
|
+
{
|
|
4089
|
+
"name": "ExposedPageCapability",
|
|
4090
|
+
"kind": "interface",
|
|
4091
|
+
"jsdoc": "",
|
|
4092
|
+
"decl": "export interface ExposedPageCapability {\n module: Record<string, unknown>;\n methods: readonly string[];\n}"
|
|
4093
|
+
},
|
|
4094
|
+
{
|
|
4095
|
+
"name": "exposeCapabilitiesToPage",
|
|
4096
|
+
"kind": "function",
|
|
4097
|
+
"jsdoc": "/**\n * Expose selected typed @himalaya/* modules to the hosting page.\n *\n * The worker author must pass both the imported module and its explicit verb allowlist:\n *\n * import * as health from \"@himalaya/health\";\n * exposeCapabilitiesToPage({\n * health: { module: health, methods: [\"availability\", \"query\"] },\n * });\n *\n * The bundle still has to declare `webview` plus every exposed capability. Importing only\n * selected modules keeps native permissions and `himi dist` additions opt-in.\n */",
|
|
4098
|
+
"decl": "export function exposeCapabilitiesToPage(\n capabilities: Readonly<Record<string, ExposedPageCapability>>,\n): void;"
|
|
4099
|
+
},
|
|
4100
|
+
{
|
|
4101
|
+
"name": "version",
|
|
4102
|
+
"kind": "const",
|
|
4103
|
+
"jsdoc": "",
|
|
4104
|
+
"decl": "export const version = 1;"
|
|
4105
|
+
}
|
|
4106
|
+
]
|
|
4107
|
+
},
|
|
4108
|
+
{
|
|
4109
|
+
"name": "@himalaya/webview-page",
|
|
4110
|
+
"source": "core/sdk/webview-page/src/index.ts",
|
|
4111
|
+
"description": "browser-side SDK for a trusted page hosted by a worker-backed Himalaya WebView.",
|
|
4112
|
+
"api": [
|
|
4113
|
+
{
|
|
4114
|
+
"name": "\"./capabilities.generated.js\"",
|
|
4115
|
+
"kind": "reexport",
|
|
4116
|
+
"jsdoc": "",
|
|
4117
|
+
"decl": "export type { HimalayaPageCapabilities, HimalayaPageSdk } from \"./capabilities.generated.js\";"
|
|
4118
|
+
},
|
|
4119
|
+
{
|
|
4120
|
+
"name": "WebViewPageRequest",
|
|
4121
|
+
"kind": "interface",
|
|
4122
|
+
"jsdoc": "",
|
|
4123
|
+
"decl": "export interface WebViewPageRequest {\n v: 1;\n id: string;\n capability: string;\n method: string;\n args: unknown[];\n}"
|
|
4124
|
+
},
|
|
4125
|
+
{
|
|
4126
|
+
"name": "WebViewPageError",
|
|
4127
|
+
"kind": "interface",
|
|
4128
|
+
"jsdoc": "",
|
|
4129
|
+
"decl": "export interface WebViewPageError {\n message: string;\n code?: string;\n}"
|
|
4130
|
+
},
|
|
4131
|
+
{
|
|
4132
|
+
"name": "WebViewPageResponse",
|
|
4133
|
+
"kind": "interface",
|
|
4134
|
+
"jsdoc": "",
|
|
4135
|
+
"decl": "export interface WebViewPageResponse {\n v: 1;\n id: string;\n ok: boolean;\n result?: unknown;\n error?: WebViewPageError;\n}"
|
|
4136
|
+
},
|
|
4137
|
+
{
|
|
4138
|
+
"name": "call",
|
|
4139
|
+
"kind": "function",
|
|
4140
|
+
"jsdoc": "/** Invoke one method through the companion worker. Primarily useful to generated bindings. */",
|
|
4141
|
+
"decl": "export function call<T>(\n capability: string,\n method: string,\n args: unknown[] = [],\n timeoutMs = 30_000,\n): Promise<T>;"
|
|
4142
|
+
},
|
|
4143
|
+
{
|
|
4144
|
+
"name": "himalaya",
|
|
4145
|
+
"kind": "const",
|
|
4146
|
+
"jsdoc": "/**\n * Typed SDK proxy for every request/response capability in CAPABILITY_REGISTRY.\n * A namespace is usable only when this screen's companion worker explicitly imported and\n * exposed it and the bundle + host both declared it.\n */",
|
|
4147
|
+
"decl": "export const himalaya = new Proxy({ version: 1 as const }, {\n get(target, property) {\n if (property === \"version\") return target.version;\n if (typeof property !== \"string\" || property === \"then\") return undefined;\n return pageMember(property, []);\n },\n}) as HimalayaPageSdk;"
|
|
4148
|
+
},
|
|
4149
|
+
{
|
|
4150
|
+
"name": "health",
|
|
4151
|
+
"kind": "const",
|
|
4152
|
+
"jsdoc": "/** Convenience named export; equivalent to `himalaya.health`. */",
|
|
4153
|
+
"decl": "export const health = himalaya.health;"
|
|
4154
|
+
},
|
|
4076
4155
|
{
|
|
4077
4156
|
"name": "version",
|
|
4078
4157
|
"kind": "const",
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Himalaya SDK for hosted WebView pages
|
|
2
|
+
|
|
3
|
+
Use `@wix/himalaya/webview-page` when a trusted webpage hosted inside Brandy (or another
|
|
4
|
+
worker-backed Himalaya WebView) needs an explicitly selected native capability. The webpage never
|
|
5
|
+
talks directly to native code:
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
page → window.HimalayaWorker → companion Tier-5 worker → @himalaya/* → native registry
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The same bundle declaration and host policy that protect an ordinary Tier-5 screen protect the
|
|
12
|
+
page. A namespace present in TypeScript is not authority: the companion worker must import and
|
|
13
|
+
allowlist it, its `logicBundle.declaredCapabilities` must name it, and the binary must serve it.
|
|
14
|
+
|
|
15
|
+
## Page
|
|
16
|
+
|
|
17
|
+
Install the published umbrella package and import its page entry:
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { himalaya } from "@wix/himalaya/webview-page";
|
|
21
|
+
|
|
22
|
+
const available = await himalaya.health.availability();
|
|
23
|
+
if (available.available) {
|
|
24
|
+
await himalaya.health.requestPermission({ read: ["steps"], write: ["workouts"] });
|
|
25
|
+
const result = await himalaya.health.query({
|
|
26
|
+
type: "steps",
|
|
27
|
+
from: new Date("2026-10-11T00:00:00Z").toISOString(),
|
|
28
|
+
to: new Date().toISOString(),
|
|
29
|
+
});
|
|
30
|
+
console.log(result.samples);
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The generated `himalaya` type includes every package represented by
|
|
35
|
+
`CAPABILITY_REGISTRY`, including nested APIs such as `himalaya.base44.auth.*`. Calls made in an
|
|
36
|
+
ordinary browser fail immediately with a clear “not inside a worker-backed Himalaya WebView”
|
|
37
|
+
error.
|
|
38
|
+
|
|
39
|
+
## Companion worker
|
|
40
|
+
|
|
41
|
+
Import only what this website is allowed to use and allowlist only the methods it needs:
|
|
42
|
+
|
|
43
|
+
```ts
|
|
44
|
+
import * as health from "@himalaya/health";
|
|
45
|
+
import { exposeCapabilitiesToPage } from "@himalaya/webview";
|
|
46
|
+
|
|
47
|
+
exposeCapabilitiesToPage({
|
|
48
|
+
health: {
|
|
49
|
+
module: health,
|
|
50
|
+
methods: ["availability", "requestPermission", "getPermissionStatus", "query", "saveWorkout"],
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Build it like any other Tier-5 bundle. Its descriptor must declare both the transport and the
|
|
56
|
+
selected capabilities:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
logicBundle: {
|
|
60
|
+
url,
|
|
61
|
+
integrity,
|
|
62
|
+
declaredCapabilities: ["webview", "health"],
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Do not build one worker that imports every SDK. Static bundle scanning would correctly conclude
|
|
67
|
+
that the release uses every capability, forcing unrelated permissions and native modules into the
|
|
68
|
+
binary. One app-specific worker imports exactly the app’s selected subset.
|
|
69
|
+
|
|
70
|
+
## Brandy
|
|
71
|
+
|
|
72
|
+
Health has a built-in proof worker, so it needs no custom bundle name:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"webSdk": {
|
|
77
|
+
"capabilities": ["health"],
|
|
78
|
+
"permissionCopy": {
|
|
79
|
+
"health": "Show your activity and save completed workouts."
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
For another subset, add the companion bundle to the app and name it:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"webSdk": {
|
|
90
|
+
"bundle": "customer-page-capabilities",
|
|
91
|
+
"capabilities": ["camera", "share"],
|
|
92
|
+
"permissionCopy": {
|
|
93
|
+
"camera": "Take a photo to attach it to your request."
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Brandy accepts capabilities `himi dist` can add to an extensible shell. Capabilities requiring
|
|
100
|
+
app-specific boot wiring remain refused until that shell supplies the wiring. Base44 is accepted
|
|
101
|
+
only when the same Brandy contract contains a Base44 binding.
|
|
102
|
+
|
|
103
|
+
## Security and current transport boundary
|
|
104
|
+
|
|
105
|
+
- Only the trusted main-frame origin receives `HimalayaWorker`; redirects and cross-origin frames
|
|
106
|
+
cannot use it.
|
|
107
|
+
- The worker accepts JSON-compatible arguments and results, caps argument count, validates request
|
|
108
|
+
identifiers and resolves only own properties on an explicit method allowlist.
|
|
109
|
+
- Errors preserve a typed `code` when the SDK provides one.
|
|
110
|
+
- The page cannot use raw `capability.*` messages: Brandy site descriptors keep
|
|
111
|
+
`capabilitiesRequired: []`; native calls go through the companion worker.
|
|
112
|
+
- v1 is request/response. SDK helpers returning `AsyncIterable`, accepting JavaScript callbacks,
|
|
113
|
+
or depending on worker action names need a page-specific adapter built from their lower-level
|
|
114
|
+
start/next/stop verbs. Do not expose such a helper unchanged.
|
|
115
|
+
|
|
116
|
+
The package source includes complete `health-page.ts` and `health-worker.ts` examples matching the
|
|
117
|
+
snippets above.
|
|
118
|
+
|
|
119
|
+
## Demo app regression page
|
|
120
|
+
|
|
121
|
+
The demo app hosts a page that calls every capability its iOS and Android boots already
|
|
122
|
+
register. Open it with:
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
himalaya-demo-app://screen/demo_app_webview_sdk
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The page is served at `/web/webview-sdk.html`. Its companion worker is
|
|
129
|
+
`demo-app-webview-sdk`, which carries the catalog of allowlisted methods and read-only
|
|
130
|
+
probes. Safe probes run on load.
|
|
131
|
+
Verbs that prompt, write, or open system UI stay allowlisted and are not called. Streaming
|
|
132
|
+
helpers that return a live object stay on the worker.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wix/himalaya-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1294.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "himi — the Himalaya authoring CLI. Build a Tier-5 content package on your own machine, push it to the production serve as a draft, preview it on web + Himi Player, and read worker logs back — the remote dev loop. Wraps @himalaya/serve-cli for transport.",
|
|
6
6
|
"keywords": [
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"artifactId": "himalaya-cli"
|
|
71
71
|
}
|
|
72
72
|
},
|
|
73
|
-
"falconPackageHash": "
|
|
73
|
+
"falconPackageHash": "09e12b3c3f8e23efc26c5fee02873fd0f086030be36e989ccb20d835"
|
|
74
74
|
}
|
|
@@ -24242,6 +24242,25 @@ const SCREENS = runtimeSetting({
|
|
|
24242
24242
|
},
|
|
24243
24243
|
}) as Record<string, unknown>;
|
|
24244
24244
|
|
|
24245
|
+
// The language destination stays registered for deep links and future translations. Keep its
|
|
24246
|
+
// account entry out of a single-language app; adding a locale to config.locale.translations
|
|
24247
|
+
// makes the same entry visible after the app config reloads.
|
|
24248
|
+
const localeConfig = config.locale as { default?: string; translations?: readonly string[] } | undefined;
|
|
24249
|
+
const configuredLocales = new Set([localeConfig?.default ?? "en", ...(localeConfig?.translations ?? [])]);
|
|
24250
|
+
if (localeConfig && configuredLocales.size <= 1) {
|
|
24251
|
+
const removeLanguageEntry = (value: unknown): unknown => {
|
|
24252
|
+
if (Array.isArray(value)) return value.flatMap((child) => {
|
|
24253
|
+
const next = removeLanguageEntry(child);
|
|
24254
|
+
return next === undefined ? [] : [next];
|
|
24255
|
+
});
|
|
24256
|
+
if (!value || typeof value !== "object") return value;
|
|
24257
|
+
const node = value as Record<string, unknown>;
|
|
24258
|
+
if (node.id === "himi_account.language") return undefined;
|
|
24259
|
+
return Object.fromEntries(Object.entries(node).map(([key, child]) => [key, removeLanguageEntry(child)]));
|
|
24260
|
+
};
|
|
24261
|
+
const account = SCREENS["himi_account"] as { payload?: unknown } | undefined;
|
|
24262
|
+
if (account?.payload) account.payload = removeLanguageEntry(account.payload);
|
|
24263
|
+
}
|
|
24245
24264
|
interface LiveSeed { path: string; body: unknown; listKey: string; prefix: string; limit?: number }
|
|
24246
24265
|
const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; staticSeedIds?: string[]; template: unknown }[] = [
|
|
24247
24266
|
{ pattern: "^himi_order(?:[_/](.+))?$", display: "himi_order[_{id}]", template: {
|
|
@@ -80521,6 +80521,25 @@ const SCREENS = runtimeSetting({
|
|
|
80521
80521
|
},
|
|
80522
80522
|
}) as Record<string, unknown>;
|
|
80523
80523
|
|
|
80524
|
+
// The language destination stays registered for deep links and future translations. Keep its
|
|
80525
|
+
// account entry out of a single-language app; adding a locale to config.locale.translations
|
|
80526
|
+
// makes the same entry visible after the app config reloads.
|
|
80527
|
+
const localeConfig = config.locale as { default?: string; translations?: readonly string[] } | undefined;
|
|
80528
|
+
const configuredLocales = new Set([localeConfig?.default ?? "en", ...(localeConfig?.translations ?? [])]);
|
|
80529
|
+
if (localeConfig && configuredLocales.size <= 1) {
|
|
80530
|
+
const removeLanguageEntry = (value: unknown): unknown => {
|
|
80531
|
+
if (Array.isArray(value)) return value.flatMap((child) => {
|
|
80532
|
+
const next = removeLanguageEntry(child);
|
|
80533
|
+
return next === undefined ? [] : [next];
|
|
80534
|
+
});
|
|
80535
|
+
if (!value || typeof value !== "object") return value;
|
|
80536
|
+
const node = value as Record<string, unknown>;
|
|
80537
|
+
if (node.id === "himi_account.language") return undefined;
|
|
80538
|
+
return Object.fromEntries(Object.entries(node).map(([key, child]) => [key, removeLanguageEntry(child)]));
|
|
80539
|
+
};
|
|
80540
|
+
const account = SCREENS["himi_account"] as { payload?: unknown } | undefined;
|
|
80541
|
+
if (account?.payload) account.payload = removeLanguageEntry(account.payload);
|
|
80542
|
+
}
|
|
80524
80543
|
interface LiveSeed { path: string; body: unknown; listKey: string; prefix: string; limit?: number }
|
|
80525
80544
|
const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; staticSeedIds?: string[]; template: unknown }[] = [
|
|
80526
80545
|
{ pattern: "^himi_order(?:[_/](.+))?$", display: "himi_order[_{id}]", template: {
|
|
@@ -17012,6 +17012,25 @@ const SCREENS = runtimeSetting({
|
|
|
17012
17012
|
},
|
|
17013
17013
|
}) as Record<string, unknown>;
|
|
17014
17014
|
|
|
17015
|
+
// The language destination stays registered for deep links and future translations. Keep its
|
|
17016
|
+
// account entry out of a single-language app; adding a locale to config.locale.translations
|
|
17017
|
+
// makes the same entry visible after the app config reloads.
|
|
17018
|
+
const localeConfig = config.locale as { default?: string; translations?: readonly string[] } | undefined;
|
|
17019
|
+
const configuredLocales = new Set([localeConfig?.default ?? "en", ...(localeConfig?.translations ?? [])]);
|
|
17020
|
+
if (localeConfig && configuredLocales.size <= 1) {
|
|
17021
|
+
const removeLanguageEntry = (value: unknown): unknown => {
|
|
17022
|
+
if (Array.isArray(value)) return value.flatMap((child) => {
|
|
17023
|
+
const next = removeLanguageEntry(child);
|
|
17024
|
+
return next === undefined ? [] : [next];
|
|
17025
|
+
});
|
|
17026
|
+
if (!value || typeof value !== "object") return value;
|
|
17027
|
+
const node = value as Record<string, unknown>;
|
|
17028
|
+
if (node.id === "himi_account.language") return undefined;
|
|
17029
|
+
return Object.fromEntries(Object.entries(node).map(([key, child]) => [key, removeLanguageEntry(child)]));
|
|
17030
|
+
};
|
|
17031
|
+
const account = SCREENS["himi_account"] as { payload?: unknown } | undefined;
|
|
17032
|
+
if (account?.payload) account.payload = removeLanguageEntry(account.payload);
|
|
17033
|
+
}
|
|
17015
17034
|
interface LiveSeed { path: string; body: unknown; listKey: string; prefix: string; limit?: number }
|
|
17016
17035
|
const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; staticSeedIds?: string[]; template: unknown }[] = [
|
|
17017
17036
|
{ pattern: "^himi_event(?:[_/](.+))?$", display: "himi_event[_{id}]", liveSeed: {"path":"/events/v3/events/query","body":{"query":{"paging":{"limit":50}}},"listKey":"events","prefix":"himi_event_"}, template: {
|
|
@@ -15010,6 +15010,25 @@ const SCREENS = runtimeSetting({
|
|
|
15010
15010
|
},
|
|
15011
15011
|
}) as Record<string, unknown>;
|
|
15012
15012
|
|
|
15013
|
+
// The language destination stays registered for deep links and future translations. Keep its
|
|
15014
|
+
// account entry out of a single-language app; adding a locale to config.locale.translations
|
|
15015
|
+
// makes the same entry visible after the app config reloads.
|
|
15016
|
+
const localeConfig = config.locale as { default?: string; translations?: readonly string[] } | undefined;
|
|
15017
|
+
const configuredLocales = new Set([localeConfig?.default ?? "en", ...(localeConfig?.translations ?? [])]);
|
|
15018
|
+
if (localeConfig && configuredLocales.size <= 1) {
|
|
15019
|
+
const removeLanguageEntry = (value: unknown): unknown => {
|
|
15020
|
+
if (Array.isArray(value)) return value.flatMap((child) => {
|
|
15021
|
+
const next = removeLanguageEntry(child);
|
|
15022
|
+
return next === undefined ? [] : [next];
|
|
15023
|
+
});
|
|
15024
|
+
if (!value || typeof value !== "object") return value;
|
|
15025
|
+
const node = value as Record<string, unknown>;
|
|
15026
|
+
if (node.id === "himi_account.language") return undefined;
|
|
15027
|
+
return Object.fromEntries(Object.entries(node).map(([key, child]) => [key, removeLanguageEntry(child)]));
|
|
15028
|
+
};
|
|
15029
|
+
const account = SCREENS["himi_account"] as { payload?: unknown } | undefined;
|
|
15030
|
+
if (account?.payload) account.payload = removeLanguageEntry(account.payload);
|
|
15031
|
+
}
|
|
15013
15032
|
interface LiveSeed { path: string; body: unknown; listKey: string; prefix: string; limit?: number }
|
|
15014
15033
|
const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; staticSeedIds?: string[]; template: unknown }[] = [
|
|
15015
15034
|
{ pattern: "^himi_event(?:[_/](.+))?$", display: "himi_event[_{id}]", liveSeed: {"path":"/events/v3/events/query","body":{"query":{"paging":{"limit":50}}},"listKey":"events","prefix":"himi_event_"}, template: {
|
|
@@ -28843,6 +28843,25 @@ const SCREENS = runtimeSetting({
|
|
|
28843
28843
|
},
|
|
28844
28844
|
}) as Record<string, unknown>;
|
|
28845
28845
|
|
|
28846
|
+
// The language destination stays registered for deep links and future translations. Keep its
|
|
28847
|
+
// account entry out of a single-language app; adding a locale to config.locale.translations
|
|
28848
|
+
// makes the same entry visible after the app config reloads.
|
|
28849
|
+
const localeConfig = config.locale as { default?: string; translations?: readonly string[] } | undefined;
|
|
28850
|
+
const configuredLocales = new Set([localeConfig?.default ?? "en", ...(localeConfig?.translations ?? [])]);
|
|
28851
|
+
if (localeConfig && configuredLocales.size <= 1) {
|
|
28852
|
+
const removeLanguageEntry = (value: unknown): unknown => {
|
|
28853
|
+
if (Array.isArray(value)) return value.flatMap((child) => {
|
|
28854
|
+
const next = removeLanguageEntry(child);
|
|
28855
|
+
return next === undefined ? [] : [next];
|
|
28856
|
+
});
|
|
28857
|
+
if (!value || typeof value !== "object") return value;
|
|
28858
|
+
const node = value as Record<string, unknown>;
|
|
28859
|
+
if (node.id === "himi_account.language") return undefined;
|
|
28860
|
+
return Object.fromEntries(Object.entries(node).map(([key, child]) => [key, removeLanguageEntry(child)]));
|
|
28861
|
+
};
|
|
28862
|
+
const account = SCREENS["himi_account"] as { payload?: unknown } | undefined;
|
|
28863
|
+
if (account?.payload) account.payload = removeLanguageEntry(account.payload);
|
|
28864
|
+
}
|
|
28846
28865
|
interface LiveSeed { path: string; body: unknown; listKey: string; prefix: string; limit?: number }
|
|
28847
28866
|
const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; staticSeedIds?: string[]; template: unknown }[] = [
|
|
28848
28867
|
{ pattern: "^himi_order(?:[_/](.+))?$", display: "himi_order[_{id}]", template: {
|
|
@@ -18297,6 +18297,25 @@ const SCREENS = runtimeSetting({
|
|
|
18297
18297
|
},
|
|
18298
18298
|
}) as Record<string, unknown>;
|
|
18299
18299
|
|
|
18300
|
+
// The language destination stays registered for deep links and future translations. Keep its
|
|
18301
|
+
// account entry out of a single-language app; adding a locale to config.locale.translations
|
|
18302
|
+
// makes the same entry visible after the app config reloads.
|
|
18303
|
+
const localeConfig = config.locale as { default?: string; translations?: readonly string[] } | undefined;
|
|
18304
|
+
const configuredLocales = new Set([localeConfig?.default ?? "en", ...(localeConfig?.translations ?? [])]);
|
|
18305
|
+
if (localeConfig && configuredLocales.size <= 1) {
|
|
18306
|
+
const removeLanguageEntry = (value: unknown): unknown => {
|
|
18307
|
+
if (Array.isArray(value)) return value.flatMap((child) => {
|
|
18308
|
+
const next = removeLanguageEntry(child);
|
|
18309
|
+
return next === undefined ? [] : [next];
|
|
18310
|
+
});
|
|
18311
|
+
if (!value || typeof value !== "object") return value;
|
|
18312
|
+
const node = value as Record<string, unknown>;
|
|
18313
|
+
if (node.id === "himi_account.language") return undefined;
|
|
18314
|
+
return Object.fromEntries(Object.entries(node).map(([key, child]) => [key, removeLanguageEntry(child)]));
|
|
18315
|
+
};
|
|
18316
|
+
const account = SCREENS["himi_account"] as { payload?: unknown } | undefined;
|
|
18317
|
+
if (account?.payload) account.payload = removeLanguageEntry(account.payload);
|
|
18318
|
+
}
|
|
18300
18319
|
interface LiveSeed { path: string; body: unknown; listKey: string; prefix: string; limit?: number }
|
|
18301
18320
|
const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; staticSeedIds?: string[]; template: unknown }[] = [
|
|
18302
18321
|
{ pattern: "^himi_event(?:[_/](.+))?$", display: "himi_event[_{id}]", liveSeed: {"path":"/events/v3/events/query","body":{"query":{"paging":{"limit":50}}},"listKey":"events","prefix":"himi_event_"}, template: {
|
|
@@ -18650,6 +18650,25 @@ const SCREENS = runtimeSetting({
|
|
|
18650
18650
|
},
|
|
18651
18651
|
}) as Record<string, unknown>;
|
|
18652
18652
|
|
|
18653
|
+
// The language destination stays registered for deep links and future translations. Keep its
|
|
18654
|
+
// account entry out of a single-language app; adding a locale to config.locale.translations
|
|
18655
|
+
// makes the same entry visible after the app config reloads.
|
|
18656
|
+
const localeConfig = config.locale as { default?: string; translations?: readonly string[] } | undefined;
|
|
18657
|
+
const configuredLocales = new Set([localeConfig?.default ?? "en", ...(localeConfig?.translations ?? [])]);
|
|
18658
|
+
if (localeConfig && configuredLocales.size <= 1) {
|
|
18659
|
+
const removeLanguageEntry = (value: unknown): unknown => {
|
|
18660
|
+
if (Array.isArray(value)) return value.flatMap((child) => {
|
|
18661
|
+
const next = removeLanguageEntry(child);
|
|
18662
|
+
return next === undefined ? [] : [next];
|
|
18663
|
+
});
|
|
18664
|
+
if (!value || typeof value !== "object") return value;
|
|
18665
|
+
const node = value as Record<string, unknown>;
|
|
18666
|
+
if (node.id === "himi_account.language") return undefined;
|
|
18667
|
+
return Object.fromEntries(Object.entries(node).map(([key, child]) => [key, removeLanguageEntry(child)]));
|
|
18668
|
+
};
|
|
18669
|
+
const account = SCREENS["himi_account"] as { payload?: unknown } | undefined;
|
|
18670
|
+
if (account?.payload) account.payload = removeLanguageEntry(account.payload);
|
|
18671
|
+
}
|
|
18653
18672
|
interface LiveSeed { path: string; body: unknown; listKey: string; prefix: string; limit?: number }
|
|
18654
18673
|
const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; staticSeedIds?: string[]; template: unknown }[] = [
|
|
18655
18674
|
{ pattern: "^himi_event(?:[_/](.+))?$", display: "himi_event[_{id}]", liveSeed: {"path":"/events/v3/events/query","body":{"query":{"paging":{"limit":50}}},"listKey":"events","prefix":"himi_event_"}, template: {
|
|
@@ -21025,6 +21025,25 @@ const SCREENS = runtimeSetting({
|
|
|
21025
21025
|
},
|
|
21026
21026
|
}) as Record<string, unknown>;
|
|
21027
21027
|
|
|
21028
|
+
// The language destination stays registered for deep links and future translations. Keep its
|
|
21029
|
+
// account entry out of a single-language app; adding a locale to config.locale.translations
|
|
21030
|
+
// makes the same entry visible after the app config reloads.
|
|
21031
|
+
const localeConfig = config.locale as { default?: string; translations?: readonly string[] } | undefined;
|
|
21032
|
+
const configuredLocales = new Set([localeConfig?.default ?? "en", ...(localeConfig?.translations ?? [])]);
|
|
21033
|
+
if (localeConfig && configuredLocales.size <= 1) {
|
|
21034
|
+
const removeLanguageEntry = (value: unknown): unknown => {
|
|
21035
|
+
if (Array.isArray(value)) return value.flatMap((child) => {
|
|
21036
|
+
const next = removeLanguageEntry(child);
|
|
21037
|
+
return next === undefined ? [] : [next];
|
|
21038
|
+
});
|
|
21039
|
+
if (!value || typeof value !== "object") return value;
|
|
21040
|
+
const node = value as Record<string, unknown>;
|
|
21041
|
+
if (node.id === "himi_account.language") return undefined;
|
|
21042
|
+
return Object.fromEntries(Object.entries(node).map(([key, child]) => [key, removeLanguageEntry(child)]));
|
|
21043
|
+
};
|
|
21044
|
+
const account = SCREENS["himi_account"] as { payload?: unknown } | undefined;
|
|
21045
|
+
if (account?.payload) account.payload = removeLanguageEntry(account.payload);
|
|
21046
|
+
}
|
|
21028
21047
|
interface LiveSeed { path: string; body: unknown; listKey: string; prefix: string; limit?: number }
|
|
21029
21048
|
const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; staticSeedIds?: string[]; template: unknown }[] = [
|
|
21030
21049
|
{ pattern: "^himi_order(?:[_/](.+))?$", display: "himi_order[_{id}]", template: {
|
|
@@ -15374,6 +15374,25 @@ const SCREENS = runtimeSetting({
|
|
|
15374
15374
|
},
|
|
15375
15375
|
}) as Record<string, unknown>;
|
|
15376
15376
|
|
|
15377
|
+
// The language destination stays registered for deep links and future translations. Keep its
|
|
15378
|
+
// account entry out of a single-language app; adding a locale to config.locale.translations
|
|
15379
|
+
// makes the same entry visible after the app config reloads.
|
|
15380
|
+
const localeConfig = config.locale as { default?: string; translations?: readonly string[] } | undefined;
|
|
15381
|
+
const configuredLocales = new Set([localeConfig?.default ?? "en", ...(localeConfig?.translations ?? [])]);
|
|
15382
|
+
if (localeConfig && configuredLocales.size <= 1) {
|
|
15383
|
+
const removeLanguageEntry = (value: unknown): unknown => {
|
|
15384
|
+
if (Array.isArray(value)) return value.flatMap((child) => {
|
|
15385
|
+
const next = removeLanguageEntry(child);
|
|
15386
|
+
return next === undefined ? [] : [next];
|
|
15387
|
+
});
|
|
15388
|
+
if (!value || typeof value !== "object") return value;
|
|
15389
|
+
const node = value as Record<string, unknown>;
|
|
15390
|
+
if (node.id === "himi_account.language") return undefined;
|
|
15391
|
+
return Object.fromEntries(Object.entries(node).map(([key, child]) => [key, removeLanguageEntry(child)]));
|
|
15392
|
+
};
|
|
15393
|
+
const account = SCREENS["himi_account"] as { payload?: unknown } | undefined;
|
|
15394
|
+
if (account?.payload) account.payload = removeLanguageEntry(account.payload);
|
|
15395
|
+
}
|
|
15377
15396
|
interface LiveSeed { path: string; body: unknown; listKey: string; prefix: string; limit?: number }
|
|
15378
15397
|
const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; staticSeedIds?: string[]; template: unknown }[] = [
|
|
15379
15398
|
{ pattern: "^himi_menu_item(?:[_/](.+))?$", display: "himi_menu_item[_{id}]", liveSeed: {"path":"/restaurants/menus/v1/items/query","body":{"paging":{"limit":50}},"listKey":"items","prefix":"himi_menu_item_"}, template: {
|
|
@@ -14040,6 +14040,25 @@ const SCREENS = runtimeSetting({
|
|
|
14040
14040
|
},
|
|
14041
14041
|
}) as Record<string, unknown>;
|
|
14042
14042
|
|
|
14043
|
+
// The language destination stays registered for deep links and future translations. Keep its
|
|
14044
|
+
// account entry out of a single-language app; adding a locale to config.locale.translations
|
|
14045
|
+
// makes the same entry visible after the app config reloads.
|
|
14046
|
+
const localeConfig = config.locale as { default?: string; translations?: readonly string[] } | undefined;
|
|
14047
|
+
const configuredLocales = new Set([localeConfig?.default ?? "en", ...(localeConfig?.translations ?? [])]);
|
|
14048
|
+
if (localeConfig && configuredLocales.size <= 1) {
|
|
14049
|
+
const removeLanguageEntry = (value: unknown): unknown => {
|
|
14050
|
+
if (Array.isArray(value)) return value.flatMap((child) => {
|
|
14051
|
+
const next = removeLanguageEntry(child);
|
|
14052
|
+
return next === undefined ? [] : [next];
|
|
14053
|
+
});
|
|
14054
|
+
if (!value || typeof value !== "object") return value;
|
|
14055
|
+
const node = value as Record<string, unknown>;
|
|
14056
|
+
if (node.id === "himi_account.language") return undefined;
|
|
14057
|
+
return Object.fromEntries(Object.entries(node).map(([key, child]) => [key, removeLanguageEntry(child)]));
|
|
14058
|
+
};
|
|
14059
|
+
const account = SCREENS["himi_account"] as { payload?: unknown } | undefined;
|
|
14060
|
+
if (account?.payload) account.payload = removeLanguageEntry(account.payload);
|
|
14061
|
+
}
|
|
14043
14062
|
interface LiveSeed { path: string; body: unknown; listKey: string; prefix: string; limit?: number }
|
|
14044
14063
|
const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; staticSeedIds?: string[]; template: unknown }[] = [
|
|
14045
14064
|
{ pattern: "^himi_order(?:[_/](.+))?$", display: "himi_order[_{id}]", template: {
|
|
@@ -23895,6 +23895,25 @@ const SCREENS = runtimeSetting({
|
|
|
23895
23895
|
},
|
|
23896
23896
|
}) as Record<string, unknown>;
|
|
23897
23897
|
|
|
23898
|
+
// The language destination stays registered for deep links and future translations. Keep its
|
|
23899
|
+
// account entry out of a single-language app; adding a locale to config.locale.translations
|
|
23900
|
+
// makes the same entry visible after the app config reloads.
|
|
23901
|
+
const localeConfig = config.locale as { default?: string; translations?: readonly string[] } | undefined;
|
|
23902
|
+
const configuredLocales = new Set([localeConfig?.default ?? "en", ...(localeConfig?.translations ?? [])]);
|
|
23903
|
+
if (localeConfig && configuredLocales.size <= 1) {
|
|
23904
|
+
const removeLanguageEntry = (value: unknown): unknown => {
|
|
23905
|
+
if (Array.isArray(value)) return value.flatMap((child) => {
|
|
23906
|
+
const next = removeLanguageEntry(child);
|
|
23907
|
+
return next === undefined ? [] : [next];
|
|
23908
|
+
});
|
|
23909
|
+
if (!value || typeof value !== "object") return value;
|
|
23910
|
+
const node = value as Record<string, unknown>;
|
|
23911
|
+
if (node.id === "himi_account.language") return undefined;
|
|
23912
|
+
return Object.fromEntries(Object.entries(node).map(([key, child]) => [key, removeLanguageEntry(child)]));
|
|
23913
|
+
};
|
|
23914
|
+
const account = SCREENS["himi_account"] as { payload?: unknown } | undefined;
|
|
23915
|
+
if (account?.payload) account.payload = removeLanguageEntry(account.payload);
|
|
23916
|
+
}
|
|
23898
23917
|
interface LiveSeed { path: string; body: unknown; listKey: string; prefix: string; limit?: number }
|
|
23899
23918
|
const TEMPLATED: { pattern: string; display: string; liveSeed?: LiveSeed; staticSeedIds?: string[]; template: unknown }[] = [
|
|
23900
23919
|
{ pattern: "^himi_service(?:[_/](.+))?$", display: "himi_service[_{id}]", liveSeed: {"path":"/bookings/v2/services/query","body":{"query":{"paging":{"limit":50}}},"listKey":"services","prefix":"himi_service_"}, template: {
|