@stringpush/sdk 0.1.1 → 0.3.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 +18 -15
- package/dist/{chunk-FROJCNV7.umd.cjs → chunk-D2H2PTN2.umd.cjs} +134 -4
- package/dist/chunk-D2H2PTN2.umd.cjs.map +1 -0
- package/dist/{chunk-X3WTVBZ6.mjs → chunk-YYR2BH3L.mjs} +132 -2
- package/dist/chunk-YYR2BH3L.mjs.map +1 -0
- package/dist/{edit-launcher-PTZ5BIO2.mjs → edit-launcher-YJB2FBO7.mjs} +118 -74
- package/dist/edit-launcher-YJB2FBO7.mjs.map +1 -0
- package/dist/{edit-launcher-DB2DJSQJ.umd.cjs → edit-launcher-Z5AGCAQB.umd.cjs} +120 -76
- package/dist/edit-launcher-Z5AGCAQB.umd.cjs.map +1 -0
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.mjs +7 -3
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.cjs +19 -15
- package/dist/index.umd.cjs.map +1 -1
- package/dist/{overlay-MLOXYRPA.umd.cjs → overlay-WO46AIRO.umd.cjs} +461 -143
- package/dist/overlay-WO46AIRO.umd.cjs.map +1 -0
- package/dist/{overlay-7KC2RRGB.mjs → overlay-Y3NQFQBI.mjs} +454 -136
- package/dist/overlay-Y3NQFQBI.mjs.map +1 -0
- package/package.json +6 -6
- package/dist/chunk-FROJCNV7.umd.cjs.map +0 -1
- package/dist/chunk-X3WTVBZ6.mjs.map +0 -1
- package/dist/edit-launcher-DB2DJSQJ.umd.cjs.map +0 -1
- package/dist/edit-launcher-PTZ5BIO2.mjs.map +0 -1
- package/dist/overlay-7KC2RRGB.mjs.map +0 -1
- package/dist/overlay-MLOXYRPA.umd.cjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
adminOriginFromSignInUrl,
|
|
2
3
|
decodeEditTokenClaims,
|
|
3
4
|
isEditLauncherArmed,
|
|
4
5
|
readEditTokenFromHash,
|
|
@@ -6,7 +7,7 @@ import {
|
|
|
6
7
|
resolveEditToken,
|
|
7
8
|
shouldAutoEnableEditMode,
|
|
8
9
|
stripEditTokenFromUrl
|
|
9
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-YYR2BH3L.mjs";
|
|
10
11
|
|
|
11
12
|
// src/resolve-key.ts
|
|
12
13
|
var I18N_KEY_ATTR = "data-i18n-key";
|
|
@@ -83,7 +84,7 @@ var overlayHandle = null;
|
|
|
83
84
|
var overlayLoadPromise = null;
|
|
84
85
|
function loadOverlayModule() {
|
|
85
86
|
if (!overlayLoadPromise) {
|
|
86
|
-
overlayLoadPromise = import("./overlay-
|
|
87
|
+
overlayLoadPromise = import("./overlay-Y3NQFQBI.mjs");
|
|
87
88
|
}
|
|
88
89
|
return overlayLoadPromise;
|
|
89
90
|
}
|
|
@@ -128,6 +129,9 @@ async function enableEditMode(options = {}) {
|
|
|
128
129
|
projectId: manifest.projectId,
|
|
129
130
|
applicationId: manifest.applicationId,
|
|
130
131
|
environmentId: editClaims.environmentId,
|
|
132
|
+
environmentName: editClaims.environmentName,
|
|
133
|
+
approvalEnabled: false,
|
|
134
|
+
adminWebOrigin: initOptions.editLauncher?.signInUrl ? adminOriginFromSignInUrl(initOptions.editLauncher.signInUrl) : void 0,
|
|
131
135
|
realtimeUrl,
|
|
132
136
|
editToken,
|
|
133
137
|
apiBaseUrl,
|
|
@@ -158,7 +162,7 @@ var launcherHandle = null;
|
|
|
158
162
|
var launcherLoadPromise = null;
|
|
159
163
|
function loadLauncherModule() {
|
|
160
164
|
if (!launcherLoadPromise) {
|
|
161
|
-
launcherLoadPromise = import("./edit-launcher-
|
|
165
|
+
launcherLoadPromise = import("./edit-launcher-YJB2FBO7.mjs");
|
|
162
166
|
}
|
|
163
167
|
return launcherLoadPromise;
|
|
164
168
|
}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/resolve-key.ts","../src/index.ts","../src/edit-mode.ts","../src/runtime.ts","../src/urls.ts","../src/edit-launcher-lifecycle.ts"],"sourcesContent":["/**\n * Maps DOM nodes to translation keys for overlay edit mode (M2-SDK-02).\n *\n * Intent: host `registerResolver` first; `data-i18n-key` on the element or an ancestor is the fallback.\n */\nimport type { KeyResolver } from \"./runtime.js\";\n\nexport const I18N_KEY_ATTR = \"data-i18n-key\";\n\n/**\n * Resolves a translation key for a DOM node by walking ancestors.\n */\nexport function resolveKeyForElement(\n start: Element,\n resolver: KeyResolver | null,\n): string | null {\n if (resolver) {\n let current: Element | null = start;\n while (current) {\n const resolved = resolver(current);\n if (resolved) {\n return resolved;\n }\n current = current.parentElement;\n }\n }\n\n let current: Element | null = start;\n while (current) {\n const fromAttr = current.getAttribute(I18N_KEY_ATTR);\n if (fromAttr) {\n return fromAttr;\n }\n current = current.parentElement;\n }\n\n return null;\n}\n","/**\n * @stringpush/sdk — plain JS runtime: load manifest + bundles, expose `t()` (ICU in M1-SDK-03).\n *\n * Intent: customer-facing surface; runtime catalog/manifest delegated to @stringpush/runtime-core.\n */\nexport { I18N_KEY_ATTR } from \"./resolve-key.js\";\n\nexport type {\n EditLauncherOptions,\n EnableEditModeOptions,\n Environment,\n InitOptions,\n ManifestLocaleEntry,\n MissingKeyFallback,\n RetryOptions,\n TranslateValues,\n TranslationCatalog,\n TranslationManifest,\n} from \"./types.js\";\n\nimport type { EnableEditModeOptions, InitOptions, TranslateValues } from \"./types.js\";\nimport {\n changeLocale,\n destroyRuntime,\n getRuntime,\n getRuntimeLocale,\n initializeRuntime,\n translateKey,\n} from \"@stringpush/runtime-core\";\nimport { teardownEditLauncher, mountEditLauncherIfNeeded } from \"./edit-launcher-lifecycle.js\";\nimport {\n readEditTokenFromHash,\n readEditTokenFromQuery,\n resolveEditToken,\n shouldAutoEnableEditMode,\n stripEditTokenFromUrl,\n} from \"./edit-token.js\";\nimport {\n disableEditMode as disableEditModeInternal,\n enableEditMode as enableEditModeInternal,\n teardownEditMode,\n} from \"./edit-mode.js\";\nimport { getKeyResolver, setKeyResolver } from \"./runtime.js\";\n\n/**\n * Initialize the SDK: fetch manifest and the active locale bundle into an in-memory catalog.\n *\n * Intent: entry point for customer apps; triggers `onTranslationsUpdated` when the first catalog is ready.\n */\nexport async function init(options: InitOptions): Promise<void> {\n await initializeRuntime(options);\n\n const tokenFromUrl = readEditTokenFromQuery() ?? readEditTokenFromHash();\n if (tokenFromUrl || options.editToken) {\n resolveEditToken(options);\n if (tokenFromUrl) {\n stripEditTokenFromUrl();\n }\n }\n\n if (shouldAutoEnableEditMode(options)) {\n await enableEditModeInternal();\n } else {\n await mountEditLauncherIfNeeded(options);\n }\n}\n\nexport function destroy(): void {\n teardownEditLauncher();\n teardownEditMode();\n setKeyResolver(null);\n destroyRuntime();\n}\n\nexport function getLocale(): string {\n return getRuntimeLocale();\n}\n\n/**\n * Switch active locale and reload its bundle from the manifest.\n */\nexport async function setLocale(locale: string): Promise<void> {\n await changeLocale(locale);\n}\n\n/**\n * Translate a key using the loaded catalog and ICU MessageFormat.\n */\nexport function t(key: string, values?: TranslateValues): string {\n // Intent: preserve @stringpush/sdk error text for public `t()` callers (runtime-core uses initializeRuntime wording).\n if (!getRuntime().options) {\n throw new Error(\"@stringpush/sdk: call init() before using the runtime\");\n }\n return translateKey(key, values);\n}\n\nexport function loadNamespace(_namespace: string): Promise<void> {\n return Promise.resolve();\n}\n\nexport async function enableEditMode(options?: EnableEditModeOptions): Promise<void> {\n await enableEditModeInternal(options);\n}\n\nexport function disableEditMode(): void {\n disableEditModeInternal();\n}\n\nexport function registerResolver(resolver: (element: Element) => string | null): () => void {\n setKeyResolver(resolver);\n return () => {\n if (getKeyResolver() === resolver) {\n setKeyResolver(null);\n }\n };\n}\n","/**\n * Edit-mode lifecycle: lazy overlay chunk load and teardown (M2-SDK-01).\n */\nimport {\n patchCatalogEntry,\n resolveApiBaseUrl,\n} from \"@stringpush/runtime-core\";\nimport { decodeEditTokenClaims } from \"./edit-token-decode.js\";\nimport { resolveEditToken } from \"./edit-token.js\";\nimport { resolveKeyForElement } from \"./resolve-key.js\";\nimport { assertInitialized, getKeyResolver, getRuntime } from \"./runtime.js\";\nimport type { EnableEditModeOptions } from \"./types.js\";\nimport { resolveRealtimeUrl } from \"./urls.js\";\n\ntype OverlayModule = typeof import(\"./overlay/index.js\");\n\nlet overlayHandle: { destroy: () => void } | null = null;\nlet overlayLoadPromise: Promise<OverlayModule> | null = null;\n\nfunction loadOverlayModule(): Promise<OverlayModule> {\n if (!overlayLoadPromise) {\n // Intent: dynamic import keeps overlay + WS client out of the default SDK bundle.\n overlayLoadPromise = import(\"./overlay/index.js\");\n }\n return overlayLoadPromise;\n}\n\nexport function isEditModeActive(): boolean {\n return overlayHandle !== null;\n}\n\n/**\n * Activates overlay edit mode when a valid edit JWT is available.\n */\nexport async function enableEditMode(options: EnableEditModeOptions = {}): Promise<void> {\n if (overlayHandle) {\n return;\n }\n\n const initOptions = assertInitialized();\n const state = getRuntime();\n const manifest = state.manifest;\n if (!manifest) {\n throw new Error(\"@stringpush/sdk: manifest is not loaded — call init() before enableEditMode()\");\n }\n\n const editToken = resolveEditToken(initOptions, options.editToken);\n if (!editToken) {\n throw new Error(\n \"@stringpush/sdk: edit token required — pass editToken, ?edit_token=, or sessionStorage\",\n );\n }\n\n const apiBaseUrl = resolveApiBaseUrl(initOptions.apiBaseUrl);\n const realtimeUrl = resolveRealtimeUrl(apiBaseUrl, initOptions.realtimeUrl);\n const overlay = await loadOverlayModule();\n const editClaims = decodeEditTokenClaims(editToken);\n if (!editClaims) {\n throw new Error(\"@stringpush/sdk: edit token is malformed\");\n }\n if (editClaims.projectId !== manifest.projectId) {\n throw new Error(\"@stringpush/sdk: edit token project does not match loaded manifest\");\n }\n if (editClaims.applicationId !== manifest.applicationId) {\n throw new Error(\"@stringpush/sdk: edit token application does not match init()\");\n }\n if (editClaims.environmentName !== initOptions.environment) {\n throw new Error(\n \"@stringpush/sdk: edit token environment does not match init() environment\",\n );\n }\n\n overlayHandle = overlay.mountOverlay({\n projectId: manifest.projectId,\n applicationId: manifest.applicationId,\n environmentId: editClaims.environmentId,\n realtimeUrl,\n editToken,\n apiBaseUrl,\n origin: initOptions.origin,\n activeLocaleCode: state.locale,\n resolveKey: (element) => resolveKeyForElement(element, getKeyResolver()),\n onCatalogPatched: (keyPath, localeCode, value, version) => {\n if (patchCatalogEntry(keyPath, localeCode, value, version)) {\n initOptions.onTranslationsUpdated?.();\n }\n },\n onTranslationsUpdated: () => {\n initOptions.onTranslationsUpdated?.();\n },\n });\n}\n\n/**\n * Tears down overlay DOM and closes the realtime WebSocket.\n */\nexport function disableEditMode(): void {\n overlayHandle?.destroy();\n overlayHandle = null;\n}\n\nexport function teardownEditMode(): void {\n disableEditMode();\n overlayLoadPromise = null;\n}\n","/**\n * DOM-specific runtime helpers (key resolver) atop @stringpush/runtime-core state.\n *\n * Intent: overlay `registerResolver` stays in sdk; catalog/manifest live in runtime-core.\n */\nimport {\n assertInitialized as assertCoreInitialized,\n getRuntime,\n resetRuntime,\n type SdkRuntime,\n} from \"@stringpush/runtime-core\";\nimport type { InitOptions } from \"./types.js\";\n\nexport { getRuntime, resetRuntime, type SdkRuntime };\n\n/** SDK init stores overlay fields on the same options object passed to runtime-core. */\nexport function assertInitialized(): InitOptions {\n return assertCoreInitialized() as InitOptions;\n}\n\nexport type KeyResolver = (element: Element) => string | null;\n\nlet keyResolver: KeyResolver | null = null;\n\nexport function setKeyResolver(resolver: KeyResolver | null): void {\n keyResolver = resolver;\n}\n\nexport function getKeyResolver(): KeyResolver | null {\n return keyResolver;\n}\n","/**\n * WebSocket URL helper for overlay realtime (M2-SDK-01).\n *\n * Intent: overlay-specific; runtime-core has no realtime dependency.\n */\nexport function resolveRealtimeUrl(apiBaseUrl: string, explicit?: string): string {\n if (explicit) {\n return explicit.replace(/\\/$/, \"\");\n }\n\n const api = new URL(apiBaseUrl);\n if (api.hostname === \"localhost\" && (api.port === \"3000\" || api.port === \"\")) {\n return \"ws://localhost:3001\";\n }\n\n const protocol = api.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n return `${protocol}//${api.host}`;\n}\n","/**\n * Edit launcher mount/teardown (M2-SDK-05).\n *\n * Intent: dynamic import keeps launcher UI out of the default SDK bundle.\n */\nimport { isEditLauncherArmed, shouldAutoEnableEditMode } from \"./edit-token.js\";\nimport {\n disableEditMode as disableEditModeInternal,\n enableEditMode as enableEditModeInternal,\n isEditModeActive,\n} from \"./edit-mode.js\";\nimport type { InitOptions } from \"./types.js\";\n\ntype EditLauncherModule = typeof import(\"./edit-launcher/index.js\");\n\nlet launcherHandle: { destroy: () => void } | null = null;\nlet launcherLoadPromise: Promise<EditLauncherModule> | null = null;\n\nfunction loadLauncherModule(): Promise<EditLauncherModule> {\n if (!launcherLoadPromise) {\n launcherLoadPromise = import(\"./edit-launcher/index.js\");\n }\n return launcherLoadPromise;\n}\n\nexport function shouldMountEditLauncher(options: InitOptions): boolean {\n if (!options.editLauncher) {\n return false;\n }\n if (options.environment !== \"staging\") {\n return false;\n }\n if (shouldAutoEnableEditMode(options)) {\n return false;\n }\n return isEditLauncherArmed(options.editLauncher);\n}\n\nexport async function mountEditLauncherIfNeeded(options: InitOptions): Promise<void> {\n if (!shouldMountEditLauncher(options)) {\n return;\n }\n\n const launcherOptions = options.editLauncher!;\n const mod = await loadLauncherModule();\n launcherHandle = mod.mountEditLauncher({\n initOptions: options,\n launcherOptions,\n isEditModeActive,\n enableEditMode: () => enableEditModeInternal(),\n disableEditMode: disableEditModeInternal,\n });\n}\n\nexport function teardownEditLauncher(): void {\n launcherHandle?.destroy();\n launcherHandle = null;\n launcherLoadPromise = null;\n}\n"],"mappings":"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","names":["current","getRuntime","getRuntime","enableEditMode","disableEditMode"]}
|
|
1
|
+
{"version":3,"sources":["../src/resolve-key.ts","../src/index.ts","../src/edit-mode.ts","../src/runtime.ts","../src/urls.ts","../src/edit-launcher-lifecycle.ts"],"sourcesContent":["/**\n * Maps DOM nodes to translation keys for overlay edit mode (M2-SDK-02).\n *\n * Intent: host `registerResolver` first; `data-i18n-key` on the element or an ancestor is the fallback.\n */\nimport type { KeyResolver } from \"./runtime.js\";\n\nexport const I18N_KEY_ATTR = \"data-i18n-key\";\n\n/**\n * Resolves a translation key for a DOM node by walking ancestors.\n */\nexport function resolveKeyForElement(\n start: Element,\n resolver: KeyResolver | null,\n): string | null {\n if (resolver) {\n let current: Element | null = start;\n while (current) {\n const resolved = resolver(current);\n if (resolved) {\n return resolved;\n }\n current = current.parentElement;\n }\n }\n\n let current: Element | null = start;\n while (current) {\n const fromAttr = current.getAttribute(I18N_KEY_ATTR);\n if (fromAttr) {\n return fromAttr;\n }\n current = current.parentElement;\n }\n\n return null;\n}\n","/**\n * @stringpush/sdk — plain JS runtime: load manifest + bundles, expose `t()` (ICU in M1-SDK-03).\n *\n * Intent: customer-facing surface; runtime catalog/manifest delegated to @stringpush/runtime-core.\n */\nexport { I18N_KEY_ATTR } from \"./resolve-key.js\";\n\nexport type {\n EditLauncherOptions,\n EnableEditModeOptions,\n Environment,\n InitOptions,\n ManifestLocaleEntry,\n MissingKeyFallback,\n RetryOptions,\n TranslateValues,\n TranslationCatalog,\n TranslationManifest,\n} from \"./types.js\";\n\nimport type { EnableEditModeOptions, InitOptions, TranslateValues } from \"./types.js\";\nimport {\n changeLocale,\n destroyRuntime,\n getRuntime,\n getRuntimeLocale,\n initializeRuntime,\n translateKey,\n} from \"@stringpush/runtime-core\";\nimport { teardownEditLauncher, mountEditLauncherIfNeeded } from \"./edit-launcher-lifecycle.js\";\nimport {\n readEditTokenFromHash,\n readEditTokenFromQuery,\n resolveEditToken,\n shouldAutoEnableEditMode,\n stripEditTokenFromUrl,\n} from \"./edit-token.js\";\nimport {\n disableEditMode as disableEditModeInternal,\n enableEditMode as enableEditModeInternal,\n teardownEditMode,\n} from \"./edit-mode.js\";\nimport { getKeyResolver, setKeyResolver } from \"./runtime.js\";\n\n/**\n * Initialize the SDK: fetch manifest and the active locale bundle into an in-memory catalog.\n *\n * Intent: entry point for customer apps; triggers `onTranslationsUpdated` when the first catalog is ready.\n */\nexport async function init(options: InitOptions): Promise<void> {\n await initializeRuntime(options);\n\n const tokenFromUrl = readEditTokenFromQuery() ?? readEditTokenFromHash();\n if (tokenFromUrl || options.editToken) {\n resolveEditToken(options);\n if (tokenFromUrl) {\n stripEditTokenFromUrl();\n }\n }\n\n if (shouldAutoEnableEditMode(options)) {\n await enableEditModeInternal();\n } else {\n await mountEditLauncherIfNeeded(options);\n }\n}\n\nexport function destroy(): void {\n teardownEditLauncher();\n teardownEditMode();\n setKeyResolver(null);\n destroyRuntime();\n}\n\nexport function getLocale(): string {\n return getRuntimeLocale();\n}\n\n/**\n * Switch active locale and reload its bundle from the manifest.\n */\nexport async function setLocale(locale: string): Promise<void> {\n await changeLocale(locale);\n}\n\n/**\n * Translate a key using the loaded catalog and ICU MessageFormat.\n */\nexport function t(key: string, values?: TranslateValues): string {\n // Intent: preserve @stringpush/sdk error text for public `t()` callers (runtime-core uses initializeRuntime wording).\n if (!getRuntime().options) {\n throw new Error(\"@stringpush/sdk: call init() before using the runtime\");\n }\n return translateKey(key, values);\n}\n\nexport function loadNamespace(_namespace: string): Promise<void> {\n return Promise.resolve();\n}\n\nexport async function enableEditMode(options?: EnableEditModeOptions): Promise<void> {\n await enableEditModeInternal(options);\n}\n\nexport function disableEditMode(): void {\n disableEditModeInternal();\n}\n\nexport function registerResolver(resolver: (element: Element) => string | null): () => void {\n setKeyResolver(resolver);\n return () => {\n if (getKeyResolver() === resolver) {\n setKeyResolver(null);\n }\n };\n}\n","/**\n * Edit-mode lifecycle: lazy overlay chunk load and teardown (M2-SDK-01).\n */\nimport {\n patchCatalogEntry,\n resolveApiBaseUrl,\n} from \"@stringpush/runtime-core\";\nimport { decodeEditTokenClaims } from \"./edit-token-decode.js\";\nimport { adminOriginFromSignInUrl } from \"./edit-launcher/sign-in-popup.js\";\nimport { resolveEditToken } from \"./edit-token.js\";\nimport { resolveKeyForElement } from \"./resolve-key.js\";\nimport { assertInitialized, getKeyResolver, getRuntime } from \"./runtime.js\";\nimport type { EnableEditModeOptions } from \"./types.js\";\nimport { resolveRealtimeUrl } from \"./urls.js\";\n\ntype OverlayModule = typeof import(\"./overlay/index.js\");\n\nlet overlayHandle: { destroy: () => void } | null = null;\nlet overlayLoadPromise: Promise<OverlayModule> | null = null;\n\nfunction loadOverlayModule(): Promise<OverlayModule> {\n if (!overlayLoadPromise) {\n // Intent: dynamic import keeps overlay + WS client out of the default SDK bundle.\n overlayLoadPromise = import(\"./overlay/index.js\");\n }\n return overlayLoadPromise;\n}\n\nexport function isEditModeActive(): boolean {\n return overlayHandle !== null;\n}\n\n/**\n * Activates overlay edit mode when a valid edit JWT is available.\n */\nexport async function enableEditMode(options: EnableEditModeOptions = {}): Promise<void> {\n if (overlayHandle) {\n return;\n }\n\n const initOptions = assertInitialized();\n const state = getRuntime();\n const manifest = state.manifest;\n if (!manifest) {\n throw new Error(\"@stringpush/sdk: manifest is not loaded — call init() before enableEditMode()\");\n }\n\n const editToken = resolveEditToken(initOptions, options.editToken);\n if (!editToken) {\n throw new Error(\n \"@stringpush/sdk: edit token required — pass editToken, ?edit_token=, or sessionStorage\",\n );\n }\n\n const apiBaseUrl = resolveApiBaseUrl(initOptions.apiBaseUrl);\n const realtimeUrl = resolveRealtimeUrl(apiBaseUrl, initOptions.realtimeUrl);\n const overlay = await loadOverlayModule();\n const editClaims = decodeEditTokenClaims(editToken);\n if (!editClaims) {\n throw new Error(\"@stringpush/sdk: edit token is malformed\");\n }\n if (editClaims.projectId !== manifest.projectId) {\n throw new Error(\"@stringpush/sdk: edit token project does not match loaded manifest\");\n }\n if (editClaims.applicationId !== manifest.applicationId) {\n throw new Error(\"@stringpush/sdk: edit token application does not match init()\");\n }\n if (editClaims.environmentName !== initOptions.environment) {\n throw new Error(\n \"@stringpush/sdk: edit token environment does not match init() environment\",\n );\n }\n\n overlayHandle = overlay.mountOverlay({\n projectId: manifest.projectId,\n applicationId: manifest.applicationId,\n environmentId: editClaims.environmentId,\n environmentName: editClaims.environmentName,\n approvalEnabled: false,\n adminWebOrigin: initOptions.editLauncher?.signInUrl\n ? adminOriginFromSignInUrl(initOptions.editLauncher.signInUrl)\n : undefined,\n realtimeUrl,\n editToken,\n apiBaseUrl,\n origin: initOptions.origin,\n activeLocaleCode: state.locale,\n resolveKey: (element) => resolveKeyForElement(element, getKeyResolver()),\n onCatalogPatched: (keyPath, localeCode, value, version) => {\n if (patchCatalogEntry(keyPath, localeCode, value, version)) {\n initOptions.onTranslationsUpdated?.();\n }\n },\n onTranslationsUpdated: () => {\n initOptions.onTranslationsUpdated?.();\n },\n });\n}\n\n/**\n * Tears down overlay DOM and closes the realtime WebSocket.\n */\nexport function disableEditMode(): void {\n overlayHandle?.destroy();\n overlayHandle = null;\n}\n\nexport function teardownEditMode(): void {\n disableEditMode();\n overlayLoadPromise = null;\n}\n","/**\n * DOM-specific runtime helpers (key resolver) atop @stringpush/runtime-core state.\n *\n * Intent: overlay `registerResolver` stays in sdk; catalog/manifest live in runtime-core.\n */\nimport {\n assertInitialized as assertCoreInitialized,\n getRuntime,\n resetRuntime,\n type SdkRuntime,\n} from \"@stringpush/runtime-core\";\nimport type { InitOptions } from \"./types.js\";\n\nexport { getRuntime, resetRuntime, type SdkRuntime };\n\n/** SDK init stores overlay fields on the same options object passed to runtime-core. */\nexport function assertInitialized(): InitOptions {\n return assertCoreInitialized() as InitOptions;\n}\n\nexport type KeyResolver = (element: Element) => string | null;\n\nlet keyResolver: KeyResolver | null = null;\n\nexport function setKeyResolver(resolver: KeyResolver | null): void {\n keyResolver = resolver;\n}\n\nexport function getKeyResolver(): KeyResolver | null {\n return keyResolver;\n}\n","/**\n * WebSocket URL helper for overlay realtime (M2-SDK-01).\n *\n * Intent: overlay-specific; runtime-core has no realtime dependency.\n */\nexport function resolveRealtimeUrl(apiBaseUrl: string, explicit?: string): string {\n if (explicit) {\n return explicit.replace(/\\/$/, \"\");\n }\n\n const api = new URL(apiBaseUrl);\n if (api.hostname === \"localhost\" && (api.port === \"3000\" || api.port === \"\")) {\n return \"ws://localhost:3001\";\n }\n\n const protocol = api.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n return `${protocol}//${api.host}`;\n}\n","/**\n * Edit launcher mount/teardown (M2-SDK-05).\n *\n * Intent: dynamic import keeps launcher UI out of the default SDK bundle.\n */\nimport { isEditLauncherArmed, shouldAutoEnableEditMode } from \"./edit-token.js\";\nimport {\n disableEditMode as disableEditModeInternal,\n enableEditMode as enableEditModeInternal,\n isEditModeActive,\n} from \"./edit-mode.js\";\nimport type { InitOptions } from \"./types.js\";\n\ntype EditLauncherModule = typeof import(\"./edit-launcher/index.js\");\n\nlet launcherHandle: { destroy: () => void } | null = null;\nlet launcherLoadPromise: Promise<EditLauncherModule> | null = null;\n\nfunction loadLauncherModule(): Promise<EditLauncherModule> {\n if (!launcherLoadPromise) {\n launcherLoadPromise = import(\"./edit-launcher/index.js\");\n }\n return launcherLoadPromise;\n}\n\nexport function shouldMountEditLauncher(options: InitOptions): boolean {\n if (!options.editLauncher) {\n return false;\n }\n if (options.environment !== \"staging\") {\n return false;\n }\n if (shouldAutoEnableEditMode(options)) {\n return false;\n }\n return isEditLauncherArmed(options.editLauncher);\n}\n\nexport async function mountEditLauncherIfNeeded(options: InitOptions): Promise<void> {\n if (!shouldMountEditLauncher(options)) {\n return;\n }\n\n const launcherOptions = options.editLauncher!;\n const mod = await loadLauncherModule();\n launcherHandle = mod.mountEditLauncher({\n initOptions: options,\n launcherOptions,\n isEditModeActive,\n enableEditMode: () => enableEditModeInternal(),\n disableEditMode: disableEditModeInternal,\n });\n}\n\nexport function teardownEditLauncher(): void {\n launcherHandle?.destroy();\n launcherHandle = null;\n launcherLoadPromise = null;\n}\n"],"mappings":"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","names":["current","getRuntime","getRuntime","enableEditMode","disableEditMode"]}
|
package/dist/index.umd.cjs
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
var _chunkD2H2PTN2umdcjs = require('./chunk-D2H2PTN2.umd.cjs');
|
|
10
11
|
|
|
11
12
|
// src/resolve-key.ts
|
|
12
13
|
var I18N_KEY_ATTR = "data-i18n-key";
|
|
@@ -83,7 +84,7 @@ var overlayHandle = null;
|
|
|
83
84
|
var overlayLoadPromise = null;
|
|
84
85
|
function loadOverlayModule() {
|
|
85
86
|
if (!overlayLoadPromise) {
|
|
86
|
-
overlayLoadPromise = Promise.resolve().then(() => _interopRequireWildcard(require("./overlay-
|
|
87
|
+
overlayLoadPromise = Promise.resolve().then(() => _interopRequireWildcard(require("./overlay-WO46AIRO.umd.cjs")));
|
|
87
88
|
}
|
|
88
89
|
return overlayLoadPromise;
|
|
89
90
|
}
|
|
@@ -100,7 +101,7 @@ async function enableEditMode(options = {}) {
|
|
|
100
101
|
if (!manifest) {
|
|
101
102
|
throw new Error("@stringpush/sdk: manifest is not loaded \u2014 call init() before enableEditMode()");
|
|
102
103
|
}
|
|
103
|
-
const editToken =
|
|
104
|
+
const editToken = _chunkD2H2PTN2umdcjs.resolveEditToken.call(void 0, initOptions, options.editToken);
|
|
104
105
|
if (!editToken) {
|
|
105
106
|
throw new Error(
|
|
106
107
|
"@stringpush/sdk: edit token required \u2014 pass editToken, ?edit_token=, or sessionStorage"
|
|
@@ -109,7 +110,7 @@ async function enableEditMode(options = {}) {
|
|
|
109
110
|
const apiBaseUrl = _runtimecore.resolveApiBaseUrl.call(void 0, initOptions.apiBaseUrl);
|
|
110
111
|
const realtimeUrl = resolveRealtimeUrl(apiBaseUrl, initOptions.realtimeUrl);
|
|
111
112
|
const overlay = await loadOverlayModule();
|
|
112
|
-
const editClaims =
|
|
113
|
+
const editClaims = _chunkD2H2PTN2umdcjs.decodeEditTokenClaims.call(void 0, editToken);
|
|
113
114
|
if (!editClaims) {
|
|
114
115
|
throw new Error("@stringpush/sdk: edit token is malformed");
|
|
115
116
|
}
|
|
@@ -128,6 +129,9 @@ async function enableEditMode(options = {}) {
|
|
|
128
129
|
projectId: manifest.projectId,
|
|
129
130
|
applicationId: manifest.applicationId,
|
|
130
131
|
environmentId: editClaims.environmentId,
|
|
132
|
+
environmentName: editClaims.environmentName,
|
|
133
|
+
approvalEnabled: false,
|
|
134
|
+
adminWebOrigin: _optionalChain([initOptions, 'access', _ => _.editLauncher, 'optionalAccess', _2 => _2.signInUrl]) ? _chunkD2H2PTN2umdcjs.adminOriginFromSignInUrl.call(void 0, initOptions.editLauncher.signInUrl) : void 0,
|
|
131
135
|
realtimeUrl,
|
|
132
136
|
editToken,
|
|
133
137
|
apiBaseUrl,
|
|
@@ -136,16 +140,16 @@ async function enableEditMode(options = {}) {
|
|
|
136
140
|
resolveKey: (element) => resolveKeyForElement(element, getKeyResolver()),
|
|
137
141
|
onCatalogPatched: (keyPath, localeCode, value, version) => {
|
|
138
142
|
if (_runtimecore.patchCatalogEntry.call(void 0, keyPath, localeCode, value, version)) {
|
|
139
|
-
_optionalChain([initOptions, 'access',
|
|
143
|
+
_optionalChain([initOptions, 'access', _3 => _3.onTranslationsUpdated, 'optionalCall', _4 => _4()]);
|
|
140
144
|
}
|
|
141
145
|
},
|
|
142
146
|
onTranslationsUpdated: () => {
|
|
143
|
-
_optionalChain([initOptions, 'access',
|
|
147
|
+
_optionalChain([initOptions, 'access', _5 => _5.onTranslationsUpdated, 'optionalCall', _6 => _6()]);
|
|
144
148
|
}
|
|
145
149
|
});
|
|
146
150
|
}
|
|
147
151
|
function disableEditMode() {
|
|
148
|
-
_optionalChain([overlayHandle, 'optionalAccess',
|
|
152
|
+
_optionalChain([overlayHandle, 'optionalAccess', _7 => _7.destroy, 'call', _8 => _8()]);
|
|
149
153
|
overlayHandle = null;
|
|
150
154
|
}
|
|
151
155
|
function teardownEditMode() {
|
|
@@ -158,7 +162,7 @@ var launcherHandle = null;
|
|
|
158
162
|
var launcherLoadPromise = null;
|
|
159
163
|
function loadLauncherModule() {
|
|
160
164
|
if (!launcherLoadPromise) {
|
|
161
|
-
launcherLoadPromise = Promise.resolve().then(() => _interopRequireWildcard(require("./edit-launcher-
|
|
165
|
+
launcherLoadPromise = Promise.resolve().then(() => _interopRequireWildcard(require("./edit-launcher-Z5AGCAQB.umd.cjs")));
|
|
162
166
|
}
|
|
163
167
|
return launcherLoadPromise;
|
|
164
168
|
}
|
|
@@ -169,10 +173,10 @@ function shouldMountEditLauncher(options) {
|
|
|
169
173
|
if (options.environment !== "staging") {
|
|
170
174
|
return false;
|
|
171
175
|
}
|
|
172
|
-
if (
|
|
176
|
+
if (_chunkD2H2PTN2umdcjs.shouldAutoEnableEditMode.call(void 0, options)) {
|
|
173
177
|
return false;
|
|
174
178
|
}
|
|
175
|
-
return
|
|
179
|
+
return _chunkD2H2PTN2umdcjs.isEditLauncherArmed.call(void 0, options.editLauncher);
|
|
176
180
|
}
|
|
177
181
|
async function mountEditLauncherIfNeeded(options) {
|
|
178
182
|
if (!shouldMountEditLauncher(options)) {
|
|
@@ -189,7 +193,7 @@ async function mountEditLauncherIfNeeded(options) {
|
|
|
189
193
|
});
|
|
190
194
|
}
|
|
191
195
|
function teardownEditLauncher() {
|
|
192
|
-
_optionalChain([launcherHandle, 'optionalAccess',
|
|
196
|
+
_optionalChain([launcherHandle, 'optionalAccess', _9 => _9.destroy, 'call', _10 => _10()]);
|
|
193
197
|
launcherHandle = null;
|
|
194
198
|
launcherLoadPromise = null;
|
|
195
199
|
}
|
|
@@ -197,14 +201,14 @@ function teardownEditLauncher() {
|
|
|
197
201
|
// src/index.ts
|
|
198
202
|
async function init(options) {
|
|
199
203
|
await _runtimecore.initializeRuntime.call(void 0, options);
|
|
200
|
-
const tokenFromUrl = _nullishCoalesce(
|
|
204
|
+
const tokenFromUrl = _nullishCoalesce(_chunkD2H2PTN2umdcjs.readEditTokenFromQuery.call(void 0, ), () => ( _chunkD2H2PTN2umdcjs.readEditTokenFromHash.call(void 0, )));
|
|
201
205
|
if (tokenFromUrl || options.editToken) {
|
|
202
|
-
|
|
206
|
+
_chunkD2H2PTN2umdcjs.resolveEditToken.call(void 0, options);
|
|
203
207
|
if (tokenFromUrl) {
|
|
204
|
-
|
|
208
|
+
_chunkD2H2PTN2umdcjs.stripEditTokenFromUrl.call(void 0, );
|
|
205
209
|
}
|
|
206
210
|
}
|
|
207
|
-
if (
|
|
211
|
+
if (_chunkD2H2PTN2umdcjs.shouldAutoEnableEditMode.call(void 0, options)) {
|
|
208
212
|
await enableEditMode();
|
|
209
213
|
} else {
|
|
210
214
|
await mountEditLauncherIfNeeded(options);
|
package/dist/index.umd.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/translations/translations/packages/sdk/dist/index.umd.cjs","../src/resolve-key.ts","../src/index.ts","../src/edit-mode.ts","../src/runtime.ts","../src/urls.ts","../src/edit-launcher-lifecycle.ts"],"names":["current","getRuntime","disableEditMode"],"mappings":"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","file":"/home/runner/work/translations/translations/packages/sdk/dist/index.umd.cjs","sourcesContent":[null,"/**\n * Maps DOM nodes to translation keys for overlay edit mode (M2-SDK-02).\n *\n * Intent: host `registerResolver` first; `data-i18n-key` on the element or an ancestor is the fallback.\n */\nimport type { KeyResolver } from \"./runtime.js\";\n\nexport const I18N_KEY_ATTR = \"data-i18n-key\";\n\n/**\n * Resolves a translation key for a DOM node by walking ancestors.\n */\nexport function resolveKeyForElement(\n start: Element,\n resolver: KeyResolver | null,\n): string | null {\n if (resolver) {\n let current: Element | null = start;\n while (current) {\n const resolved = resolver(current);\n if (resolved) {\n return resolved;\n }\n current = current.parentElement;\n }\n }\n\n let current: Element | null = start;\n while (current) {\n const fromAttr = current.getAttribute(I18N_KEY_ATTR);\n if (fromAttr) {\n return fromAttr;\n }\n current = current.parentElement;\n }\n\n return null;\n}\n","/**\n * @stringpush/sdk — plain JS runtime: load manifest + bundles, expose `t()` (ICU in M1-SDK-03).\n *\n * Intent: customer-facing surface; runtime catalog/manifest delegated to @stringpush/runtime-core.\n */\nexport { I18N_KEY_ATTR } from \"./resolve-key.js\";\n\nexport type {\n EditLauncherOptions,\n EnableEditModeOptions,\n Environment,\n InitOptions,\n ManifestLocaleEntry,\n MissingKeyFallback,\n RetryOptions,\n TranslateValues,\n TranslationCatalog,\n TranslationManifest,\n} from \"./types.js\";\n\nimport type { EnableEditModeOptions, InitOptions, TranslateValues } from \"./types.js\";\nimport {\n changeLocale,\n destroyRuntime,\n getRuntime,\n getRuntimeLocale,\n initializeRuntime,\n translateKey,\n} from \"@stringpush/runtime-core\";\nimport { teardownEditLauncher, mountEditLauncherIfNeeded } from \"./edit-launcher-lifecycle.js\";\nimport {\n readEditTokenFromHash,\n readEditTokenFromQuery,\n resolveEditToken,\n shouldAutoEnableEditMode,\n stripEditTokenFromUrl,\n} from \"./edit-token.js\";\nimport {\n disableEditMode as disableEditModeInternal,\n enableEditMode as enableEditModeInternal,\n teardownEditMode,\n} from \"./edit-mode.js\";\nimport { getKeyResolver, setKeyResolver } from \"./runtime.js\";\n\n/**\n * Initialize the SDK: fetch manifest and the active locale bundle into an in-memory catalog.\n *\n * Intent: entry point for customer apps; triggers `onTranslationsUpdated` when the first catalog is ready.\n */\nexport async function init(options: InitOptions): Promise<void> {\n await initializeRuntime(options);\n\n const tokenFromUrl = readEditTokenFromQuery() ?? readEditTokenFromHash();\n if (tokenFromUrl || options.editToken) {\n resolveEditToken(options);\n if (tokenFromUrl) {\n stripEditTokenFromUrl();\n }\n }\n\n if (shouldAutoEnableEditMode(options)) {\n await enableEditModeInternal();\n } else {\n await mountEditLauncherIfNeeded(options);\n }\n}\n\nexport function destroy(): void {\n teardownEditLauncher();\n teardownEditMode();\n setKeyResolver(null);\n destroyRuntime();\n}\n\nexport function getLocale(): string {\n return getRuntimeLocale();\n}\n\n/**\n * Switch active locale and reload its bundle from the manifest.\n */\nexport async function setLocale(locale: string): Promise<void> {\n await changeLocale(locale);\n}\n\n/**\n * Translate a key using the loaded catalog and ICU MessageFormat.\n */\nexport function t(key: string, values?: TranslateValues): string {\n // Intent: preserve @stringpush/sdk error text for public `t()` callers (runtime-core uses initializeRuntime wording).\n if (!getRuntime().options) {\n throw new Error(\"@stringpush/sdk: call init() before using the runtime\");\n }\n return translateKey(key, values);\n}\n\nexport function loadNamespace(_namespace: string): Promise<void> {\n return Promise.resolve();\n}\n\nexport async function enableEditMode(options?: EnableEditModeOptions): Promise<void> {\n await enableEditModeInternal(options);\n}\n\nexport function disableEditMode(): void {\n disableEditModeInternal();\n}\n\nexport function registerResolver(resolver: (element: Element) => string | null): () => void {\n setKeyResolver(resolver);\n return () => {\n if (getKeyResolver() === resolver) {\n setKeyResolver(null);\n }\n };\n}\n","/**\n * Edit-mode lifecycle: lazy overlay chunk load and teardown (M2-SDK-01).\n */\nimport {\n patchCatalogEntry,\n resolveApiBaseUrl,\n} from \"@stringpush/runtime-core\";\nimport { decodeEditTokenClaims } from \"./edit-token-decode.js\";\nimport { resolveEditToken } from \"./edit-token.js\";\nimport { resolveKeyForElement } from \"./resolve-key.js\";\nimport { assertInitialized, getKeyResolver, getRuntime } from \"./runtime.js\";\nimport type { EnableEditModeOptions } from \"./types.js\";\nimport { resolveRealtimeUrl } from \"./urls.js\";\n\ntype OverlayModule = typeof import(\"./overlay/index.js\");\n\nlet overlayHandle: { destroy: () => void } | null = null;\nlet overlayLoadPromise: Promise<OverlayModule> | null = null;\n\nfunction loadOverlayModule(): Promise<OverlayModule> {\n if (!overlayLoadPromise) {\n // Intent: dynamic import keeps overlay + WS client out of the default SDK bundle.\n overlayLoadPromise = import(\"./overlay/index.js\");\n }\n return overlayLoadPromise;\n}\n\nexport function isEditModeActive(): boolean {\n return overlayHandle !== null;\n}\n\n/**\n * Activates overlay edit mode when a valid edit JWT is available.\n */\nexport async function enableEditMode(options: EnableEditModeOptions = {}): Promise<void> {\n if (overlayHandle) {\n return;\n }\n\n const initOptions = assertInitialized();\n const state = getRuntime();\n const manifest = state.manifest;\n if (!manifest) {\n throw new Error(\"@stringpush/sdk: manifest is not loaded — call init() before enableEditMode()\");\n }\n\n const editToken = resolveEditToken(initOptions, options.editToken);\n if (!editToken) {\n throw new Error(\n \"@stringpush/sdk: edit token required — pass editToken, ?edit_token=, or sessionStorage\",\n );\n }\n\n const apiBaseUrl = resolveApiBaseUrl(initOptions.apiBaseUrl);\n const realtimeUrl = resolveRealtimeUrl(apiBaseUrl, initOptions.realtimeUrl);\n const overlay = await loadOverlayModule();\n const editClaims = decodeEditTokenClaims(editToken);\n if (!editClaims) {\n throw new Error(\"@stringpush/sdk: edit token is malformed\");\n }\n if (editClaims.projectId !== manifest.projectId) {\n throw new Error(\"@stringpush/sdk: edit token project does not match loaded manifest\");\n }\n if (editClaims.applicationId !== manifest.applicationId) {\n throw new Error(\"@stringpush/sdk: edit token application does not match init()\");\n }\n if (editClaims.environmentName !== initOptions.environment) {\n throw new Error(\n \"@stringpush/sdk: edit token environment does not match init() environment\",\n );\n }\n\n overlayHandle = overlay.mountOverlay({\n projectId: manifest.projectId,\n applicationId: manifest.applicationId,\n environmentId: editClaims.environmentId,\n realtimeUrl,\n editToken,\n apiBaseUrl,\n origin: initOptions.origin,\n activeLocaleCode: state.locale,\n resolveKey: (element) => resolveKeyForElement(element, getKeyResolver()),\n onCatalogPatched: (keyPath, localeCode, value, version) => {\n if (patchCatalogEntry(keyPath, localeCode, value, version)) {\n initOptions.onTranslationsUpdated?.();\n }\n },\n onTranslationsUpdated: () => {\n initOptions.onTranslationsUpdated?.();\n },\n });\n}\n\n/**\n * Tears down overlay DOM and closes the realtime WebSocket.\n */\nexport function disableEditMode(): void {\n overlayHandle?.destroy();\n overlayHandle = null;\n}\n\nexport function teardownEditMode(): void {\n disableEditMode();\n overlayLoadPromise = null;\n}\n","/**\n * DOM-specific runtime helpers (key resolver) atop @stringpush/runtime-core state.\n *\n * Intent: overlay `registerResolver` stays in sdk; catalog/manifest live in runtime-core.\n */\nimport {\n assertInitialized as assertCoreInitialized,\n getRuntime,\n resetRuntime,\n type SdkRuntime,\n} from \"@stringpush/runtime-core\";\nimport type { InitOptions } from \"./types.js\";\n\nexport { getRuntime, resetRuntime, type SdkRuntime };\n\n/** SDK init stores overlay fields on the same options object passed to runtime-core. */\nexport function assertInitialized(): InitOptions {\n return assertCoreInitialized() as InitOptions;\n}\n\nexport type KeyResolver = (element: Element) => string | null;\n\nlet keyResolver: KeyResolver | null = null;\n\nexport function setKeyResolver(resolver: KeyResolver | null): void {\n keyResolver = resolver;\n}\n\nexport function getKeyResolver(): KeyResolver | null {\n return keyResolver;\n}\n","/**\n * WebSocket URL helper for overlay realtime (M2-SDK-01).\n *\n * Intent: overlay-specific; runtime-core has no realtime dependency.\n */\nexport function resolveRealtimeUrl(apiBaseUrl: string, explicit?: string): string {\n if (explicit) {\n return explicit.replace(/\\/$/, \"\");\n }\n\n const api = new URL(apiBaseUrl);\n if (api.hostname === \"localhost\" && (api.port === \"3000\" || api.port === \"\")) {\n return \"ws://localhost:3001\";\n }\n\n const protocol = api.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n return `${protocol}//${api.host}`;\n}\n","/**\n * Edit launcher mount/teardown (M2-SDK-05).\n *\n * Intent: dynamic import keeps launcher UI out of the default SDK bundle.\n */\nimport { isEditLauncherArmed, shouldAutoEnableEditMode } from \"./edit-token.js\";\nimport {\n disableEditMode as disableEditModeInternal,\n enableEditMode as enableEditModeInternal,\n isEditModeActive,\n} from \"./edit-mode.js\";\nimport type { InitOptions } from \"./types.js\";\n\ntype EditLauncherModule = typeof import(\"./edit-launcher/index.js\");\n\nlet launcherHandle: { destroy: () => void } | null = null;\nlet launcherLoadPromise: Promise<EditLauncherModule> | null = null;\n\nfunction loadLauncherModule(): Promise<EditLauncherModule> {\n if (!launcherLoadPromise) {\n launcherLoadPromise = import(\"./edit-launcher/index.js\");\n }\n return launcherLoadPromise;\n}\n\nexport function shouldMountEditLauncher(options: InitOptions): boolean {\n if (!options.editLauncher) {\n return false;\n }\n if (options.environment !== \"staging\") {\n return false;\n }\n if (shouldAutoEnableEditMode(options)) {\n return false;\n }\n return isEditLauncherArmed(options.editLauncher);\n}\n\nexport async function mountEditLauncherIfNeeded(options: InitOptions): Promise<void> {\n if (!shouldMountEditLauncher(options)) {\n return;\n }\n\n const launcherOptions = options.editLauncher!;\n const mod = await loadLauncherModule();\n launcherHandle = mod.mountEditLauncher({\n initOptions: options,\n launcherOptions,\n isEditModeActive,\n enableEditMode: () => enableEditModeInternal(),\n disableEditMode: disableEditModeInternal,\n });\n}\n\nexport function teardownEditLauncher(): void {\n launcherHandle?.destroy();\n launcherHandle = null;\n launcherLoadPromise = null;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/translations/translations/packages/sdk/dist/index.umd.cjs","../src/resolve-key.ts","../src/index.ts","../src/edit-mode.ts","../src/runtime.ts","../src/urls.ts","../src/edit-launcher-lifecycle.ts"],"names":["current","getRuntime","disableEditMode"],"mappings":"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","file":"/home/runner/work/translations/translations/packages/sdk/dist/index.umd.cjs","sourcesContent":[null,"/**\n * Maps DOM nodes to translation keys for overlay edit mode (M2-SDK-02).\n *\n * Intent: host `registerResolver` first; `data-i18n-key` on the element or an ancestor is the fallback.\n */\nimport type { KeyResolver } from \"./runtime.js\";\n\nexport const I18N_KEY_ATTR = \"data-i18n-key\";\n\n/**\n * Resolves a translation key for a DOM node by walking ancestors.\n */\nexport function resolveKeyForElement(\n start: Element,\n resolver: KeyResolver | null,\n): string | null {\n if (resolver) {\n let current: Element | null = start;\n while (current) {\n const resolved = resolver(current);\n if (resolved) {\n return resolved;\n }\n current = current.parentElement;\n }\n }\n\n let current: Element | null = start;\n while (current) {\n const fromAttr = current.getAttribute(I18N_KEY_ATTR);\n if (fromAttr) {\n return fromAttr;\n }\n current = current.parentElement;\n }\n\n return null;\n}\n","/**\n * @stringpush/sdk — plain JS runtime: load manifest + bundles, expose `t()` (ICU in M1-SDK-03).\n *\n * Intent: customer-facing surface; runtime catalog/manifest delegated to @stringpush/runtime-core.\n */\nexport { I18N_KEY_ATTR } from \"./resolve-key.js\";\n\nexport type {\n EditLauncherOptions,\n EnableEditModeOptions,\n Environment,\n InitOptions,\n ManifestLocaleEntry,\n MissingKeyFallback,\n RetryOptions,\n TranslateValues,\n TranslationCatalog,\n TranslationManifest,\n} from \"./types.js\";\n\nimport type { EnableEditModeOptions, InitOptions, TranslateValues } from \"./types.js\";\nimport {\n changeLocale,\n destroyRuntime,\n getRuntime,\n getRuntimeLocale,\n initializeRuntime,\n translateKey,\n} from \"@stringpush/runtime-core\";\nimport { teardownEditLauncher, mountEditLauncherIfNeeded } from \"./edit-launcher-lifecycle.js\";\nimport {\n readEditTokenFromHash,\n readEditTokenFromQuery,\n resolveEditToken,\n shouldAutoEnableEditMode,\n stripEditTokenFromUrl,\n} from \"./edit-token.js\";\nimport {\n disableEditMode as disableEditModeInternal,\n enableEditMode as enableEditModeInternal,\n teardownEditMode,\n} from \"./edit-mode.js\";\nimport { getKeyResolver, setKeyResolver } from \"./runtime.js\";\n\n/**\n * Initialize the SDK: fetch manifest and the active locale bundle into an in-memory catalog.\n *\n * Intent: entry point for customer apps; triggers `onTranslationsUpdated` when the first catalog is ready.\n */\nexport async function init(options: InitOptions): Promise<void> {\n await initializeRuntime(options);\n\n const tokenFromUrl = readEditTokenFromQuery() ?? readEditTokenFromHash();\n if (tokenFromUrl || options.editToken) {\n resolveEditToken(options);\n if (tokenFromUrl) {\n stripEditTokenFromUrl();\n }\n }\n\n if (shouldAutoEnableEditMode(options)) {\n await enableEditModeInternal();\n } else {\n await mountEditLauncherIfNeeded(options);\n }\n}\n\nexport function destroy(): void {\n teardownEditLauncher();\n teardownEditMode();\n setKeyResolver(null);\n destroyRuntime();\n}\n\nexport function getLocale(): string {\n return getRuntimeLocale();\n}\n\n/**\n * Switch active locale and reload its bundle from the manifest.\n */\nexport async function setLocale(locale: string): Promise<void> {\n await changeLocale(locale);\n}\n\n/**\n * Translate a key using the loaded catalog and ICU MessageFormat.\n */\nexport function t(key: string, values?: TranslateValues): string {\n // Intent: preserve @stringpush/sdk error text for public `t()` callers (runtime-core uses initializeRuntime wording).\n if (!getRuntime().options) {\n throw new Error(\"@stringpush/sdk: call init() before using the runtime\");\n }\n return translateKey(key, values);\n}\n\nexport function loadNamespace(_namespace: string): Promise<void> {\n return Promise.resolve();\n}\n\nexport async function enableEditMode(options?: EnableEditModeOptions): Promise<void> {\n await enableEditModeInternal(options);\n}\n\nexport function disableEditMode(): void {\n disableEditModeInternal();\n}\n\nexport function registerResolver(resolver: (element: Element) => string | null): () => void {\n setKeyResolver(resolver);\n return () => {\n if (getKeyResolver() === resolver) {\n setKeyResolver(null);\n }\n };\n}\n","/**\n * Edit-mode lifecycle: lazy overlay chunk load and teardown (M2-SDK-01).\n */\nimport {\n patchCatalogEntry,\n resolveApiBaseUrl,\n} from \"@stringpush/runtime-core\";\nimport { decodeEditTokenClaims } from \"./edit-token-decode.js\";\nimport { adminOriginFromSignInUrl } from \"./edit-launcher/sign-in-popup.js\";\nimport { resolveEditToken } from \"./edit-token.js\";\nimport { resolveKeyForElement } from \"./resolve-key.js\";\nimport { assertInitialized, getKeyResolver, getRuntime } from \"./runtime.js\";\nimport type { EnableEditModeOptions } from \"./types.js\";\nimport { resolveRealtimeUrl } from \"./urls.js\";\n\ntype OverlayModule = typeof import(\"./overlay/index.js\");\n\nlet overlayHandle: { destroy: () => void } | null = null;\nlet overlayLoadPromise: Promise<OverlayModule> | null = null;\n\nfunction loadOverlayModule(): Promise<OverlayModule> {\n if (!overlayLoadPromise) {\n // Intent: dynamic import keeps overlay + WS client out of the default SDK bundle.\n overlayLoadPromise = import(\"./overlay/index.js\");\n }\n return overlayLoadPromise;\n}\n\nexport function isEditModeActive(): boolean {\n return overlayHandle !== null;\n}\n\n/**\n * Activates overlay edit mode when a valid edit JWT is available.\n */\nexport async function enableEditMode(options: EnableEditModeOptions = {}): Promise<void> {\n if (overlayHandle) {\n return;\n }\n\n const initOptions = assertInitialized();\n const state = getRuntime();\n const manifest = state.manifest;\n if (!manifest) {\n throw new Error(\"@stringpush/sdk: manifest is not loaded — call init() before enableEditMode()\");\n }\n\n const editToken = resolveEditToken(initOptions, options.editToken);\n if (!editToken) {\n throw new Error(\n \"@stringpush/sdk: edit token required — pass editToken, ?edit_token=, or sessionStorage\",\n );\n }\n\n const apiBaseUrl = resolveApiBaseUrl(initOptions.apiBaseUrl);\n const realtimeUrl = resolveRealtimeUrl(apiBaseUrl, initOptions.realtimeUrl);\n const overlay = await loadOverlayModule();\n const editClaims = decodeEditTokenClaims(editToken);\n if (!editClaims) {\n throw new Error(\"@stringpush/sdk: edit token is malformed\");\n }\n if (editClaims.projectId !== manifest.projectId) {\n throw new Error(\"@stringpush/sdk: edit token project does not match loaded manifest\");\n }\n if (editClaims.applicationId !== manifest.applicationId) {\n throw new Error(\"@stringpush/sdk: edit token application does not match init()\");\n }\n if (editClaims.environmentName !== initOptions.environment) {\n throw new Error(\n \"@stringpush/sdk: edit token environment does not match init() environment\",\n );\n }\n\n overlayHandle = overlay.mountOverlay({\n projectId: manifest.projectId,\n applicationId: manifest.applicationId,\n environmentId: editClaims.environmentId,\n environmentName: editClaims.environmentName,\n approvalEnabled: false,\n adminWebOrigin: initOptions.editLauncher?.signInUrl\n ? adminOriginFromSignInUrl(initOptions.editLauncher.signInUrl)\n : undefined,\n realtimeUrl,\n editToken,\n apiBaseUrl,\n origin: initOptions.origin,\n activeLocaleCode: state.locale,\n resolveKey: (element) => resolveKeyForElement(element, getKeyResolver()),\n onCatalogPatched: (keyPath, localeCode, value, version) => {\n if (patchCatalogEntry(keyPath, localeCode, value, version)) {\n initOptions.onTranslationsUpdated?.();\n }\n },\n onTranslationsUpdated: () => {\n initOptions.onTranslationsUpdated?.();\n },\n });\n}\n\n/**\n * Tears down overlay DOM and closes the realtime WebSocket.\n */\nexport function disableEditMode(): void {\n overlayHandle?.destroy();\n overlayHandle = null;\n}\n\nexport function teardownEditMode(): void {\n disableEditMode();\n overlayLoadPromise = null;\n}\n","/**\n * DOM-specific runtime helpers (key resolver) atop @stringpush/runtime-core state.\n *\n * Intent: overlay `registerResolver` stays in sdk; catalog/manifest live in runtime-core.\n */\nimport {\n assertInitialized as assertCoreInitialized,\n getRuntime,\n resetRuntime,\n type SdkRuntime,\n} from \"@stringpush/runtime-core\";\nimport type { InitOptions } from \"./types.js\";\n\nexport { getRuntime, resetRuntime, type SdkRuntime };\n\n/** SDK init stores overlay fields on the same options object passed to runtime-core. */\nexport function assertInitialized(): InitOptions {\n return assertCoreInitialized() as InitOptions;\n}\n\nexport type KeyResolver = (element: Element) => string | null;\n\nlet keyResolver: KeyResolver | null = null;\n\nexport function setKeyResolver(resolver: KeyResolver | null): void {\n keyResolver = resolver;\n}\n\nexport function getKeyResolver(): KeyResolver | null {\n return keyResolver;\n}\n","/**\n * WebSocket URL helper for overlay realtime (M2-SDK-01).\n *\n * Intent: overlay-specific; runtime-core has no realtime dependency.\n */\nexport function resolveRealtimeUrl(apiBaseUrl: string, explicit?: string): string {\n if (explicit) {\n return explicit.replace(/\\/$/, \"\");\n }\n\n const api = new URL(apiBaseUrl);\n if (api.hostname === \"localhost\" && (api.port === \"3000\" || api.port === \"\")) {\n return \"ws://localhost:3001\";\n }\n\n const protocol = api.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n return `${protocol}//${api.host}`;\n}\n","/**\n * Edit launcher mount/teardown (M2-SDK-05).\n *\n * Intent: dynamic import keeps launcher UI out of the default SDK bundle.\n */\nimport { isEditLauncherArmed, shouldAutoEnableEditMode } from \"./edit-token.js\";\nimport {\n disableEditMode as disableEditModeInternal,\n enableEditMode as enableEditModeInternal,\n isEditModeActive,\n} from \"./edit-mode.js\";\nimport type { InitOptions } from \"./types.js\";\n\ntype EditLauncherModule = typeof import(\"./edit-launcher/index.js\");\n\nlet launcherHandle: { destroy: () => void } | null = null;\nlet launcherLoadPromise: Promise<EditLauncherModule> | null = null;\n\nfunction loadLauncherModule(): Promise<EditLauncherModule> {\n if (!launcherLoadPromise) {\n launcherLoadPromise = import(\"./edit-launcher/index.js\");\n }\n return launcherLoadPromise;\n}\n\nexport function shouldMountEditLauncher(options: InitOptions): boolean {\n if (!options.editLauncher) {\n return false;\n }\n if (options.environment !== \"staging\") {\n return false;\n }\n if (shouldAutoEnableEditMode(options)) {\n return false;\n }\n return isEditLauncherArmed(options.editLauncher);\n}\n\nexport async function mountEditLauncherIfNeeded(options: InitOptions): Promise<void> {\n if (!shouldMountEditLauncher(options)) {\n return;\n }\n\n const launcherOptions = options.editLauncher!;\n const mod = await loadLauncherModule();\n launcherHandle = mod.mountEditLauncher({\n initOptions: options,\n launcherOptions,\n isEditModeActive,\n enableEditMode: () => enableEditModeInternal(),\n disableEditMode: disableEditModeInternal,\n });\n}\n\nexport function teardownEditLauncher(): void {\n launcherHandle?.destroy();\n launcherHandle = null;\n launcherLoadPromise = null;\n}\n"]}
|