@bleedingdev/modern-js-create 3.2.0-ultramodern.34 → 3.2.0-ultramodern.36
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/index.js +640 -35
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1209,6 +1209,11 @@ function createCloudflarePublicUrlEnv(app) {
|
|
|
1209
1209
|
return `ULTRAMODERN_PUBLIC_URL_${toEnvSegment(app.id)}`;
|
|
1210
1210
|
}
|
|
1211
1211
|
function createCloudflareProofRoute(app) {
|
|
1212
|
+
if ('shell' === app.kind) return {
|
|
1213
|
+
ssr: '/en',
|
|
1214
|
+
mfManifest: '/mf-manifest.json',
|
|
1215
|
+
locale: `/locales/en/${appI18nNamespace(app)}.json`
|
|
1216
|
+
};
|
|
1212
1217
|
const languageRoutes = createLocalisedUrlsMap(app);
|
|
1213
1218
|
const firstCanonicalPath = Object.keys(languageRoutes)[0];
|
|
1214
1219
|
const localizedPath = firstCanonicalPath && isRecord(languageRoutes[firstCanonicalPath]) ? languageRoutes[firstCanonicalPath].en : void 0;
|
|
@@ -1703,6 +1708,36 @@ function createRouteOwnedI18nPaths(app) {
|
|
|
1703
1708
|
en: '/'
|
|
1704
1709
|
},
|
|
1705
1710
|
titleKey: 'shell.title'
|
|
1711
|
+
},
|
|
1712
|
+
{
|
|
1713
|
+
...base,
|
|
1714
|
+
canonicalPath: '/tractors',
|
|
1715
|
+
id: 'shell-tractors',
|
|
1716
|
+
localisedPaths: {
|
|
1717
|
+
cs: '/traktory',
|
|
1718
|
+
en: '/tractors'
|
|
1719
|
+
},
|
|
1720
|
+
titleKey: 'shell.routes.listing'
|
|
1721
|
+
},
|
|
1722
|
+
{
|
|
1723
|
+
...base,
|
|
1724
|
+
canonicalPath: '/tractors/:slug',
|
|
1725
|
+
id: 'shell-product-detail',
|
|
1726
|
+
localisedPaths: {
|
|
1727
|
+
cs: '/traktory/:slug',
|
|
1728
|
+
en: '/tractors/:slug'
|
|
1729
|
+
},
|
|
1730
|
+
titleKey: 'shell.routes.productDetail'
|
|
1731
|
+
},
|
|
1732
|
+
{
|
|
1733
|
+
...base,
|
|
1734
|
+
canonicalPath: '/cart',
|
|
1735
|
+
id: 'shell-cart',
|
|
1736
|
+
localisedPaths: {
|
|
1737
|
+
cs: '/kosik',
|
|
1738
|
+
en: '/cart'
|
|
1739
|
+
},
|
|
1740
|
+
titleKey: 'shell.routes.cart'
|
|
1706
1741
|
}
|
|
1707
1742
|
];
|
|
1708
1743
|
if ('explore' === app.domain) return [
|
|
@@ -1959,14 +1994,18 @@ export default defineConfig(
|
|
|
1959
1994
|
}
|
|
1960
1995
|
function createAppRuntimeConfig(app) {
|
|
1961
1996
|
const namespace = appI18nNamespace(app);
|
|
1997
|
+
const localeMessages = (language)=>{
|
|
1998
|
+
if ('shell' !== app.kind) return createAppLocaleMessages(app, language);
|
|
1999
|
+
return Object.assign({}, createAppLocaleMessages(app, language), ...remoteApps.map((remote)=>createAppLocaleMessages(remote, language)));
|
|
2000
|
+
};
|
|
1962
2001
|
const resources = {
|
|
1963
2002
|
cs: {
|
|
1964
|
-
[namespace]:
|
|
1965
|
-
translation:
|
|
2003
|
+
[namespace]: localeMessages('cs'),
|
|
2004
|
+
translation: localeMessages('cs')
|
|
1966
2005
|
},
|
|
1967
2006
|
en: {
|
|
1968
|
-
[namespace]:
|
|
1969
|
-
translation:
|
|
2007
|
+
[namespace]: localeMessages('en'),
|
|
2008
|
+
translation: localeMessages('en')
|
|
1970
2009
|
}
|
|
1971
2010
|
};
|
|
1972
2011
|
return `import { defineRuntimeConfig } from '@modern-js/runtime';
|
|
@@ -2034,6 +2073,103 @@ nav {
|
|
|
2034
2073
|
a {
|
|
2035
2074
|
color: var(--um-color-link);
|
|
2036
2075
|
}
|
|
2076
|
+
|
|
2077
|
+
.commerce-shell {
|
|
2078
|
+
background: #f1eadc;
|
|
2079
|
+
color: #0b0a08;
|
|
2080
|
+
min-height: 100vh;
|
|
2081
|
+
padding: 1.5rem clamp(1rem, 4vw, 3rem) 4rem;
|
|
2082
|
+
}
|
|
2083
|
+
|
|
2084
|
+
.commerce-shell-actions {
|
|
2085
|
+
align-items: center;
|
|
2086
|
+
display: flex;
|
|
2087
|
+
flex-wrap: wrap;
|
|
2088
|
+
gap: 0.75rem;
|
|
2089
|
+
justify-content: flex-end;
|
|
2090
|
+
margin: -4.25rem auto 3rem;
|
|
2091
|
+
max-width: 88rem;
|
|
2092
|
+
}
|
|
2093
|
+
|
|
2094
|
+
.commerce-language {
|
|
2095
|
+
margin: 0;
|
|
2096
|
+
}
|
|
2097
|
+
|
|
2098
|
+
.commerce-page {
|
|
2099
|
+
margin: 3rem auto 0;
|
|
2100
|
+
max-width: 88rem;
|
|
2101
|
+
}
|
|
2102
|
+
|
|
2103
|
+
.commerce-hero {
|
|
2104
|
+
padding: 4rem 0 2rem;
|
|
2105
|
+
}
|
|
2106
|
+
|
|
2107
|
+
.commerce-eyebrow {
|
|
2108
|
+
color: #00624b;
|
|
2109
|
+
font-size: 0.85rem;
|
|
2110
|
+
font-weight: 850;
|
|
2111
|
+
letter-spacing: 0.16rem;
|
|
2112
|
+
text-transform: uppercase;
|
|
2113
|
+
}
|
|
2114
|
+
|
|
2115
|
+
.commerce-title {
|
|
2116
|
+
font-size: clamp(2.5rem, 6vw, 4.8rem);
|
|
2117
|
+
line-height: 0.95;
|
|
2118
|
+
margin: 0.65rem 0 1.4rem;
|
|
2119
|
+
max-width: 58rem;
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2122
|
+
.commerce-lede {
|
|
2123
|
+
color: #555149;
|
|
2124
|
+
font-size: 1.2rem;
|
|
2125
|
+
line-height: 1.65;
|
|
2126
|
+
max-width: 42rem;
|
|
2127
|
+
}
|
|
2128
|
+
|
|
2129
|
+
.commerce-checkout {
|
|
2130
|
+
align-items: center;
|
|
2131
|
+
display: flex;
|
|
2132
|
+
flex-wrap: wrap;
|
|
2133
|
+
gap: 0.75rem;
|
|
2134
|
+
margin-top: 1.5rem;
|
|
2135
|
+
}
|
|
2136
|
+
|
|
2137
|
+
.commerce-pill,
|
|
2138
|
+
.commerce-button,
|
|
2139
|
+
.commerce-link-button,
|
|
2140
|
+
.commerce-cart-button {
|
|
2141
|
+
align-items: center;
|
|
2142
|
+
border-radius: 999px;
|
|
2143
|
+
border: 0.0625rem solid rgba(23, 23, 23, 0.14);
|
|
2144
|
+
box-shadow: 0 0.25rem 0.75rem rgba(20, 17, 10, 0.08);
|
|
2145
|
+
color: #14120d;
|
|
2146
|
+
display: inline-flex;
|
|
2147
|
+
font: inherit;
|
|
2148
|
+
font-weight: 750;
|
|
2149
|
+
justify-content: center;
|
|
2150
|
+
min-height: 2.5rem;
|
|
2151
|
+
padding: 0.65rem 1.05rem;
|
|
2152
|
+
text-decoration: none;
|
|
2153
|
+
}
|
|
2154
|
+
|
|
2155
|
+
.commerce-button {
|
|
2156
|
+
background: #00624b;
|
|
2157
|
+
border-color: #00624b;
|
|
2158
|
+
color: #ffffff;
|
|
2159
|
+
}
|
|
2160
|
+
|
|
2161
|
+
.commerce-link-button,
|
|
2162
|
+
.commerce-pill,
|
|
2163
|
+
.commerce-cart-button {
|
|
2164
|
+
background: rgba(255, 255, 255, 0.92);
|
|
2165
|
+
}
|
|
2166
|
+
|
|
2167
|
+
@media (max-width: 860px) {
|
|
2168
|
+
.commerce-shell-actions {
|
|
2169
|
+
justify-content: flex-start;
|
|
2170
|
+
margin-top: 1rem;
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2037
2173
|
}
|
|
2038
2174
|
|
|
2039
2175
|
@layer ultramodern-shell-overlay {
|
|
@@ -2075,7 +2211,11 @@ a {
|
|
|
2075
2211
|
`;
|
|
2076
2212
|
}
|
|
2077
2213
|
function createRemoteStyles(enableTailwind, scope, app) {
|
|
2078
|
-
if (
|
|
2214
|
+
if ([
|
|
2215
|
+
'explore',
|
|
2216
|
+
'decide',
|
|
2217
|
+
'checkout'
|
|
2218
|
+
].includes(app.domain ?? '')) return `${enableTailwind ? "@import 'tailwindcss';\n" : ''}${createCssTokenImport(scope)}
|
|
2079
2219
|
|
|
2080
2220
|
@layer ultramodern-remote-${app.domain} {
|
|
2081
2221
|
.commerce-shell {
|
|
@@ -2566,13 +2706,14 @@ function createShellPage() {
|
|
|
2566
2706
|
return `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
2567
2707
|
import { Helmet } from '@modern-js/runtime/head';
|
|
2568
2708
|
import { useLocation } from '@modern-js/plugin-tanstack/runtime';
|
|
2709
|
+
import Header from 'explore/Header';
|
|
2710
|
+
import StorePicker from 'explore/StorePicker';
|
|
2711
|
+
import MiniCart from 'checkout/MiniCart';
|
|
2569
2712
|
import { ultramodernLocalisedUrls } from '../ultramodern-route-metadata';
|
|
2570
2713
|
import { ultramodernUiMarker } from '../../ultramodern-build';
|
|
2571
2714
|
|
|
2572
2715
|
const languageCodes = ['en', 'cs'] as const;
|
|
2573
2716
|
|
|
2574
|
-
const remoteKeys = ['explore', 'decide', 'checkout'] as const;
|
|
2575
|
-
|
|
2576
2717
|
${createLocalizedHeadComponent()}
|
|
2577
2718
|
export default function ShellHome() {
|
|
2578
2719
|
const { i18nInstance, language } = useModernI18n();
|
|
@@ -2581,29 +2722,169 @@ export default function ShellHome() {
|
|
|
2581
2722
|
const suffix = locationSuffix(location);
|
|
2582
2723
|
|
|
2583
2724
|
return (
|
|
2584
|
-
<main>
|
|
2725
|
+
<main className="commerce-shell">
|
|
2585
2726
|
<LocalizedHead />
|
|
2586
|
-
<
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2727
|
+
<Header />
|
|
2728
|
+
<div className="commerce-shell-actions">
|
|
2729
|
+
<nav aria-label={t('shell.language.switcher')} className="commerce-language">
|
|
2730
|
+
{languageCodes.map(code => (
|
|
2731
|
+
<a
|
|
2732
|
+
aria-current={language === code ? 'page' : undefined}
|
|
2733
|
+
className="commerce-pill"
|
|
2734
|
+
href={\`\${localizedPath(location.pathname, code)}\${suffix}\`}
|
|
2735
|
+
key={code}
|
|
2736
|
+
>
|
|
2737
|
+
{t(\`shell.language.\${code}\`)}
|
|
2738
|
+
</a>
|
|
2739
|
+
))}
|
|
2740
|
+
</nav>
|
|
2741
|
+
<MiniCart />
|
|
2742
|
+
</div>
|
|
2743
|
+
<section className="commerce-page commerce-hero">
|
|
2744
|
+
<p className="commerce-eyebrow">{t('shell.hero.eyebrow')}</p>
|
|
2745
|
+
<h1 className="commerce-title">{t('shell.title')}</h1>
|
|
2746
|
+
<p className="commerce-lede">{t('shell.hero.lede')}</p>
|
|
2747
|
+
<div className="commerce-checkout">
|
|
2748
|
+
<a className="commerce-button" href={\`/\${language}/tractors/field-loader-112\`}>
|
|
2749
|
+
{t('shell.hero.primary')}
|
|
2594
2750
|
</a>
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2751
|
+
<a className="commerce-link-button" href={\`/\${language}/tractors\`}>
|
|
2752
|
+
{t('shell.hero.secondary')}
|
|
2753
|
+
</a>
|
|
2754
|
+
</div>
|
|
2755
|
+
</section>
|
|
2756
|
+
<StorePicker />
|
|
2598
2757
|
<p data-testid="ultramodern-preset">presetUltramodern workspace</p>
|
|
2599
2758
|
<p data-build-marker={ultramodernUiMarker.build} data-testid="ultramodern-ui-marker">
|
|
2600
2759
|
{ultramodernUiMarker.appId}:{ultramodernUiMarker.version}
|
|
2601
2760
|
</p>
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2761
|
+
</main>
|
|
2762
|
+
);
|
|
2763
|
+
}
|
|
2764
|
+
`;
|
|
2765
|
+
}
|
|
2766
|
+
function createShellTractorsPage() {
|
|
2767
|
+
return `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
2768
|
+
import { Helmet } from '@modern-js/runtime/head';
|
|
2769
|
+
import { useLocation } from '@modern-js/plugin-tanstack/runtime';
|
|
2770
|
+
import Header from 'explore/Header';
|
|
2771
|
+
import Recommendations from 'explore/Recommendations';
|
|
2772
|
+
import MiniCart from 'checkout/MiniCart';
|
|
2773
|
+
import { ultramodernLocalisedUrls } from '../../ultramodern-route-metadata';
|
|
2774
|
+
|
|
2775
|
+
const languageCodes = ['en', 'cs'] as const;
|
|
2776
|
+
|
|
2777
|
+
${createLocalizedHeadComponent()}
|
|
2778
|
+
export default function ShellTractorsPage() {
|
|
2779
|
+
const { i18nInstance, language } = useModernI18n();
|
|
2780
|
+
const t = i18nInstance.t.bind(i18nInstance);
|
|
2781
|
+
const location = useLocation();
|
|
2782
|
+
const suffix = locationSuffix(location);
|
|
2783
|
+
|
|
2784
|
+
return (
|
|
2785
|
+
<main className="commerce-shell">
|
|
2786
|
+
<LocalizedHead />
|
|
2787
|
+
<Header />
|
|
2788
|
+
<div className="commerce-shell-actions">
|
|
2789
|
+
<nav aria-label={t('shell.language.switcher')} className="commerce-language">
|
|
2790
|
+
{languageCodes.map(code => (
|
|
2791
|
+
<a
|
|
2792
|
+
aria-current={language === code ? 'page' : undefined}
|
|
2793
|
+
className="commerce-pill"
|
|
2794
|
+
href={\`\${localizedPath(location.pathname, code)}\${suffix}\`}
|
|
2795
|
+
key={code}
|
|
2796
|
+
>
|
|
2797
|
+
{t(\`shell.language.\${code}\`)}
|
|
2798
|
+
</a>
|
|
2799
|
+
))}
|
|
2800
|
+
</nav>
|
|
2801
|
+
<MiniCart />
|
|
2802
|
+
</div>
|
|
2803
|
+
<Recommendations />
|
|
2804
|
+
</main>
|
|
2805
|
+
);
|
|
2806
|
+
}
|
|
2807
|
+
`;
|
|
2808
|
+
}
|
|
2809
|
+
function createShellProductPage() {
|
|
2810
|
+
return `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
2811
|
+
import { Helmet } from '@modern-js/runtime/head';
|
|
2812
|
+
import { useLocation } from '@modern-js/plugin-tanstack/runtime';
|
|
2813
|
+
import Header from 'explore/Header';
|
|
2814
|
+
import ProductPage from 'decide/ProductPage';
|
|
2815
|
+
import MiniCart from 'checkout/MiniCart';
|
|
2816
|
+
import { ultramodernLocalisedUrls } from '../../../ultramodern-route-metadata';
|
|
2817
|
+
|
|
2818
|
+
const languageCodes = ['en', 'cs'] as const;
|
|
2819
|
+
|
|
2820
|
+
${createLocalizedHeadComponent()}
|
|
2821
|
+
export default function ShellProductPage() {
|
|
2822
|
+
const { i18nInstance, language } = useModernI18n();
|
|
2823
|
+
const t = i18nInstance.t.bind(i18nInstance);
|
|
2824
|
+
const location = useLocation();
|
|
2825
|
+
const suffix = locationSuffix(location);
|
|
2826
|
+
|
|
2827
|
+
return (
|
|
2828
|
+
<main className="commerce-shell">
|
|
2829
|
+
<LocalizedHead />
|
|
2830
|
+
<Header />
|
|
2831
|
+
<div className="commerce-shell-actions">
|
|
2832
|
+
<nav aria-label={t('shell.language.switcher')} className="commerce-language">
|
|
2833
|
+
{languageCodes.map(code => (
|
|
2834
|
+
<a
|
|
2835
|
+
aria-current={language === code ? 'page' : undefined}
|
|
2836
|
+
className="commerce-pill"
|
|
2837
|
+
href={\`\${localizedPath(location.pathname, code)}\${suffix}\`}
|
|
2838
|
+
key={code}
|
|
2839
|
+
>
|
|
2840
|
+
{t(\`shell.language.\${code}\`)}
|
|
2841
|
+
</a>
|
|
2842
|
+
))}
|
|
2843
|
+
</nav>
|
|
2844
|
+
<MiniCart />
|
|
2845
|
+
</div>
|
|
2846
|
+
<ProductPage />
|
|
2847
|
+
</main>
|
|
2848
|
+
);
|
|
2849
|
+
}
|
|
2850
|
+
`;
|
|
2851
|
+
}
|
|
2852
|
+
function createShellCartPage() {
|
|
2853
|
+
return `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
2854
|
+
import { Helmet } from '@modern-js/runtime/head';
|
|
2855
|
+
import { useLocation } from '@modern-js/plugin-tanstack/runtime';
|
|
2856
|
+
import Header from 'explore/Header';
|
|
2857
|
+
import CartPage from 'checkout/CartPage';
|
|
2858
|
+
import { ultramodernLocalisedUrls } from '../../ultramodern-route-metadata';
|
|
2859
|
+
|
|
2860
|
+
const languageCodes = ['en', 'cs'] as const;
|
|
2861
|
+
|
|
2862
|
+
${createLocalizedHeadComponent()}
|
|
2863
|
+
export default function ShellCartPage() {
|
|
2864
|
+
const { i18nInstance, language } = useModernI18n();
|
|
2865
|
+
const t = i18nInstance.t.bind(i18nInstance);
|
|
2866
|
+
const location = useLocation();
|
|
2867
|
+
const suffix = locationSuffix(location);
|
|
2868
|
+
|
|
2869
|
+
return (
|
|
2870
|
+
<main className="commerce-shell">
|
|
2871
|
+
<LocalizedHead />
|
|
2872
|
+
<Header />
|
|
2873
|
+
<div className="commerce-shell-actions">
|
|
2874
|
+
<nav aria-label={t('shell.language.switcher')} className="commerce-language">
|
|
2875
|
+
{languageCodes.map(code => (
|
|
2876
|
+
<a
|
|
2877
|
+
aria-current={language === code ? 'page' : undefined}
|
|
2878
|
+
className="commerce-pill"
|
|
2879
|
+
href={\`\${localizedPath(location.pathname, code)}\${suffix}\`}
|
|
2880
|
+
key={code}
|
|
2881
|
+
>
|
|
2882
|
+
{t(\`shell.language.\${code}\`)}
|
|
2883
|
+
</a>
|
|
2884
|
+
))}
|
|
2885
|
+
</nav>
|
|
2886
|
+
</div>
|
|
2887
|
+
<CartPage />
|
|
2607
2888
|
</main>
|
|
2608
2889
|
);
|
|
2609
2890
|
}
|
|
@@ -2716,19 +2997,181 @@ function createRemoteWidget(app) {
|
|
|
2716
2997
|
`;
|
|
2717
2998
|
}
|
|
2718
2999
|
function createRemoteExposeComponent(app, expose) {
|
|
3000
|
+
if ('remote-explore' === app.id && './Header' === expose) return `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
3001
|
+
|
|
3002
|
+
export default function Header() {
|
|
3003
|
+
const { i18nInstance, language } = useModernI18n();
|
|
3004
|
+
const t = i18nInstance.t.bind(i18nInstance);
|
|
3005
|
+
|
|
3006
|
+
return (
|
|
3007
|
+
<header className="commerce-header" data-mf-boundary="explore">
|
|
3008
|
+
<a className="commerce-logo" href={\`/\${language}\`}>Acre & Iron</a>
|
|
3009
|
+
<nav aria-label={t('explore.header.navigation')} className="commerce-nav">
|
|
3010
|
+
<a href={\`/\${language}/tractors\`}>{t('explore.header.machines')}</a>
|
|
3011
|
+
<a href={\`/\${language}/stores\`}>{t('explore.header.stores')}</a>
|
|
3012
|
+
</nav>
|
|
3013
|
+
</header>
|
|
3014
|
+
);
|
|
3015
|
+
}
|
|
3016
|
+
`;
|
|
3017
|
+
if ('remote-explore' === app.id && './Recommendations' === expose) return `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
3018
|
+
|
|
3019
|
+
const tractors = [
|
|
3020
|
+
{ badge: 'explore.recommendations.bestRows', name: 'Orchard Tractor', slug: 'orchard-tractor' },
|
|
3021
|
+
{ badge: 'explore.recommendations.aiFirst', name: 'Autonomy Retrofit Kit', slug: 'autonomy-retrofit-kit' },
|
|
3022
|
+
{ badge: 'explore.recommendations.loaderReady', name: 'Field Loader 112', slug: 'field-loader-112' },
|
|
3023
|
+
{ badge: 'explore.recommendations.vineyard', name: 'Vineyard Narrow 80', slug: 'vineyard-narrow-80' },
|
|
3024
|
+
] as const;
|
|
3025
|
+
|
|
3026
|
+
export default function Recommendations() {
|
|
3027
|
+
const { i18nInstance, language } = useModernI18n();
|
|
3028
|
+
const t = i18nInstance.t.bind(i18nInstance);
|
|
3029
|
+
|
|
3030
|
+
return (
|
|
3031
|
+
<section className="commerce-page" data-mf-boundary="explore">
|
|
3032
|
+
<h2 className="commerce-section-title">{t('explore.recommendations.title')}</h2>
|
|
3033
|
+
<div className="commerce-grid">
|
|
3034
|
+
{tractors.map(tractor => (
|
|
3035
|
+
<a className="commerce-card" href={\`/\${language}/tractors/\${tractor.slug}\`} key={tractor.slug}>
|
|
3036
|
+
<span>{t(tractor.badge)}</span>
|
|
3037
|
+
<strong>{tractor.name}</strong>
|
|
3038
|
+
</a>
|
|
3039
|
+
))}
|
|
3040
|
+
</div>
|
|
3041
|
+
</section>
|
|
3042
|
+
);
|
|
3043
|
+
}
|
|
3044
|
+
`;
|
|
3045
|
+
if ('remote-explore' === app.id && './StorePicker' === expose) return `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
3046
|
+
|
|
3047
|
+
export default function StorePicker() {
|
|
3048
|
+
const { i18nInstance } = useModernI18n();
|
|
3049
|
+
const t = i18nInstance.t.bind(i18nInstance);
|
|
3050
|
+
|
|
3051
|
+
return (
|
|
3052
|
+
<section className="commerce-page" data-mf-boundary="explore">
|
|
3053
|
+
<h2 className="commerce-section-title">{t('explore.stores.title')}</h2>
|
|
3054
|
+
<div className="commerce-grid">
|
|
3055
|
+
<article className="commerce-card">
|
|
3056
|
+
<span>{t('explore.stores.northRegion')}</span>
|
|
3057
|
+
<strong>Bohemia Field Supply</strong>
|
|
3058
|
+
</article>
|
|
3059
|
+
<article className="commerce-card">
|
|
3060
|
+
<span>{t('explore.stores.southRegion')}</span>
|
|
3061
|
+
<strong>Moravia Iron Works</strong>
|
|
3062
|
+
</article>
|
|
3063
|
+
</div>
|
|
3064
|
+
</section>
|
|
3065
|
+
);
|
|
3066
|
+
}
|
|
3067
|
+
`;
|
|
3068
|
+
if ('remote-explore' === app.id && './Footer' === expose) return `export default function Footer() {
|
|
3069
|
+
return <footer className="commerce-footer" data-mf-boundary="explore">Acre & Iron</footer>;
|
|
3070
|
+
}
|
|
3071
|
+
`;
|
|
2719
3072
|
if ('./Widget' === expose) return createRemoteWidget(app);
|
|
2720
3073
|
const componentName = `${toPascalCase(app.domain ?? app.id)}${toPascalCase(expose.replace(/^\.\//u, ''))}`;
|
|
2721
|
-
if ('remote-decide' === app.id && './ProductPage' === expose) return `import
|
|
3074
|
+
if ('remote-decide' === app.id && './ProductPage' === expose) return `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
3075
|
+
import AddToCart from 'checkout/AddToCart';
|
|
2722
3076
|
import Recommendations from 'explore/Recommendations';
|
|
2723
3077
|
|
|
2724
3078
|
export default function ${componentName}() {
|
|
3079
|
+
const { i18nInstance } = useModernI18n();
|
|
3080
|
+
const t = i18nInstance.t.bind(i18nInstance);
|
|
3081
|
+
|
|
2725
3082
|
return (
|
|
2726
|
-
|
|
2727
|
-
<
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
3083
|
+
<>
|
|
3084
|
+
<section className="commerce-page commerce-product" data-mf-boundary="decide" data-mf-remote="${app.id}" data-mf-expose="${expose}">
|
|
3085
|
+
<div className="commerce-product-media" aria-hidden="true" />
|
|
3086
|
+
<div>
|
|
3087
|
+
<p className="commerce-eyebrow">{t('decide.product.eyebrow')}</p>
|
|
3088
|
+
<h1 className="commerce-title">Field Loader 112</h1>
|
|
3089
|
+
<p className="commerce-lede">{t('decide.product.lede')}</p>
|
|
3090
|
+
<div className="commerce-facts">
|
|
3091
|
+
<article className="commerce-fact"><span>{t('decide.product.price')}</span><strong>EUR 42,500</strong></article>
|
|
3092
|
+
<article className="commerce-fact"><span>{t('decide.product.power')}</span><strong>112 hp</strong></article>
|
|
3093
|
+
<article className="commerce-fact"><span>{t('decide.product.availability')}</span><strong>{t('decide.product.inStock')}</strong></article>
|
|
3094
|
+
</div>
|
|
3095
|
+
<AddToCart />
|
|
3096
|
+
</div>
|
|
3097
|
+
</section>
|
|
2731
3098
|
<Recommendations />
|
|
3099
|
+
</>
|
|
3100
|
+
);
|
|
3101
|
+
}
|
|
3102
|
+
`;
|
|
3103
|
+
if ('remote-checkout' === app.id && './AddToCart' === expose) return `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
3104
|
+
import { useCartLines } from '../cart-store';
|
|
3105
|
+
|
|
3106
|
+
export default function ${componentName}() {
|
|
3107
|
+
const { i18nInstance, language } = useModernI18n();
|
|
3108
|
+
const t = i18nInstance.t.bind(i18nInstance);
|
|
3109
|
+
const cart = useCartLines();
|
|
3110
|
+
|
|
3111
|
+
return (
|
|
3112
|
+
<div className="commerce-checkout" data-mf-boundary="checkout">
|
|
3113
|
+
<button className="commerce-button" onClick={cart.addFieldLoader} type="button">
|
|
3114
|
+
{t('checkout.actions.addToCart')}
|
|
3115
|
+
</button>
|
|
3116
|
+
<a className="commerce-link-button" href={\`/\${language}/cart\`}>
|
|
3117
|
+
{t('checkout.actions.viewCart')}
|
|
3118
|
+
</a>
|
|
3119
|
+
</div>
|
|
3120
|
+
);
|
|
3121
|
+
}
|
|
3122
|
+
`;
|
|
3123
|
+
if ('remote-checkout' === app.id && './MiniCart' === expose) return `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
3124
|
+
import { useCartLines } from '../cart-store';
|
|
3125
|
+
|
|
3126
|
+
export default function ${componentName}() {
|
|
3127
|
+
const { i18nInstance, language } = useModernI18n();
|
|
3128
|
+
const t = i18nInstance.t.bind(i18nInstance);
|
|
3129
|
+
const cart = useCartLines();
|
|
3130
|
+
const count = cart.lines.reduce((sum, line) => sum + line.quantity, 0);
|
|
3131
|
+
|
|
3132
|
+
return (
|
|
3133
|
+
<a className="commerce-cart-button" data-mf-boundary="checkout" href={\`/\${language}/cart\`}>
|
|
3134
|
+
{t('checkout.cart.title')} ({count})
|
|
3135
|
+
</a>
|
|
3136
|
+
);
|
|
3137
|
+
}
|
|
3138
|
+
`;
|
|
3139
|
+
if ('remote-checkout' === app.id && './CartPage' === expose) return `import { useModernI18n } from '@modern-js/plugin-i18n/runtime';
|
|
3140
|
+
import { useCartLines } from '../cart-store';
|
|
3141
|
+
|
|
3142
|
+
export default function ${componentName}() {
|
|
3143
|
+
const { i18nInstance } = useModernI18n();
|
|
3144
|
+
const t = i18nInstance.t.bind(i18nInstance);
|
|
3145
|
+
const cart = useCartLines();
|
|
3146
|
+
|
|
3147
|
+
return (
|
|
3148
|
+
<section className="commerce-page" data-mf-boundary="checkout" data-mf-remote="${app.id}" data-mf-expose="${expose}">
|
|
3149
|
+
<h1 className="commerce-title">{t('checkout.cart.title')}</h1>
|
|
3150
|
+
<div className="commerce-cart-panel">
|
|
3151
|
+
{cart.lines.length === 0 ? (
|
|
3152
|
+
<p>{t('checkout.cart.empty')}</p>
|
|
3153
|
+
) : (
|
|
3154
|
+
<>
|
|
3155
|
+
{cart.lines.map(line => (
|
|
3156
|
+
<article className="commerce-cart-line" key={line.id}>
|
|
3157
|
+
<div>
|
|
3158
|
+
<strong>{line.name}</strong>
|
|
3159
|
+
<p>EUR {line.price.toLocaleString('en-US')}</p>
|
|
3160
|
+
</div>
|
|
3161
|
+
<div className="commerce-quantity">
|
|
3162
|
+
<button className="commerce-quantity-button" onClick={() => cart.decrement(line.id)} type="button">-</button>
|
|
3163
|
+
<span>{line.quantity}</span>
|
|
3164
|
+
<button className="commerce-quantity-button" onClick={() => cart.increment(line.id)} type="button">+</button>
|
|
3165
|
+
<button className="commerce-link-button" onClick={() => cart.remove(line.id)} type="button">
|
|
3166
|
+
{t('checkout.actions.remove')}
|
|
3167
|
+
</button>
|
|
3168
|
+
</div>
|
|
3169
|
+
</article>
|
|
3170
|
+
))}
|
|
3171
|
+
<p><strong>{t('checkout.cart.total')}: EUR {cart.total.toLocaleString('en-US')}</strong></p>
|
|
3172
|
+
</>
|
|
3173
|
+
)}
|
|
3174
|
+
</div>
|
|
2732
3175
|
</section>
|
|
2733
3176
|
);
|
|
2734
3177
|
}
|
|
@@ -2773,6 +3216,12 @@ function createAppLocaleMessages(app, language) {
|
|
|
2773
3216
|
};
|
|
2774
3217
|
if ('shell' === app.kind) return {
|
|
2775
3218
|
shell: {
|
|
3219
|
+
hero: {
|
|
3220
|
+
eyebrow: 'en' === language ? 'Federated tractor commerce' : 'Federovaný obchod s traktory',
|
|
3221
|
+
lede: 'en' === language ? 'A full-stack Micro Vertical reference where Explore, Decide, and Checkout ship independently but compose into one storefront.' : 'Full-stack Micro Vertical ukázka, kde Procházení, Rozhodování a Pokladna vycházejí samostatně, ale skládají jeden obchod.',
|
|
3222
|
+
primary: 'en' === language ? 'View Field Loader' : 'Zobrazit Field Loader',
|
|
3223
|
+
secondary: 'en' === language ? 'Compare machines' : 'Porovnat stroje'
|
|
3224
|
+
},
|
|
2776
3225
|
language: {
|
|
2777
3226
|
cs: 'en' === language ? 'Czech' : 'Čeština',
|
|
2778
3227
|
en: 'en' === language ? 'English' : 'Angličtina',
|
|
@@ -2784,9 +3233,12 @@ function createAppLocaleMessages(app, language) {
|
|
|
2784
3233
|
explore: 'en' === language ? 'Explore Remote' : 'Explore remote'
|
|
2785
3234
|
},
|
|
2786
3235
|
routes: {
|
|
2787
|
-
|
|
3236
|
+
cart: 'en' === language ? 'Cart' : 'Košík',
|
|
3237
|
+
home: 'en' === language ? 'Home' : 'Domů',
|
|
3238
|
+
listing: 'en' === language ? 'Tractors' : 'Traktory',
|
|
3239
|
+
productDetail: 'en' === language ? 'Tractor detail' : 'Detail traktoru'
|
|
2788
3240
|
},
|
|
2789
|
-
title: 'en' === language ? '
|
|
3241
|
+
title: 'en' === language ? 'Acre & Iron' : 'Acre & Iron'
|
|
2790
3242
|
}
|
|
2791
3243
|
};
|
|
2792
3244
|
const domain = app.domain ?? app.id;
|
|
@@ -2812,7 +3264,48 @@ function createAppLocaleMessages(app, language) {
|
|
|
2812
3264
|
thankYou: 'en' === language ? 'Order confirmation' : 'Potvrzení objednávky',
|
|
2813
3265
|
unavailable: 'en' === language ? 'Unavailable' : 'Nedostupné'
|
|
2814
3266
|
},
|
|
2815
|
-
title: 'en' === language ? app.displayName : czechLabel.title
|
|
3267
|
+
title: 'en' === language ? app.displayName : czechLabel.title,
|
|
3268
|
+
...'explore' === domain ? {
|
|
3269
|
+
header: {
|
|
3270
|
+
machines: 'en' === language ? 'Machines' : 'Stroje',
|
|
3271
|
+
navigation: 'en' === language ? 'Main navigation' : 'Hlavní navigace',
|
|
3272
|
+
stores: 'en' === language ? 'Stores' : 'Prodejci'
|
|
3273
|
+
},
|
|
3274
|
+
recommendations: {
|
|
3275
|
+
aiFirst: 'en' === language ? 'AI-first option' : 'AI varianta',
|
|
3276
|
+
bestRows: 'en' === language ? 'Best for tight rows' : 'Nejlepší do úzkých řádků',
|
|
3277
|
+
loaderReady: 'en' === language ? 'Loader-ready' : 'Připraveno pro nakladač',
|
|
3278
|
+
title: 'en' === language ? 'Compare alternatives' : 'Porovnat alternativy',
|
|
3279
|
+
vineyard: 'en' === language ? 'Vineyard profile' : 'Profil pro vinice'
|
|
3280
|
+
},
|
|
3281
|
+
stores: {
|
|
3282
|
+
northRegion: 'en' === language ? 'North region' : 'Severní region',
|
|
3283
|
+
southRegion: 'en' === language ? 'South region' : 'Jižní region',
|
|
3284
|
+
title: 'en' === language ? 'Stores' : 'Prodejci'
|
|
3285
|
+
}
|
|
3286
|
+
} : {},
|
|
3287
|
+
...'decide' === domain ? {
|
|
3288
|
+
product: {
|
|
3289
|
+
availability: 'en' === language ? 'Availability' : 'Dostupnost',
|
|
3290
|
+
eyebrow: 'en' === language ? 'Machine detail' : 'Detail stroje',
|
|
3291
|
+
inStock: 'en' === language ? 'In stock' : 'Skladem',
|
|
3292
|
+
lede: 'en' === language ? 'A loader-ready tractor for feed, hay, gravel, and winter road work.' : 'Traktor připravený pro nakladač na krmivo, seno, štěrk a zimní údržbu cest.',
|
|
3293
|
+
power: 'en' === language ? 'Power' : 'Výkon',
|
|
3294
|
+
price: 'en' === language ? 'Price' : 'Cena'
|
|
3295
|
+
}
|
|
3296
|
+
} : {},
|
|
3297
|
+
...'checkout' === domain ? {
|
|
3298
|
+
actions: {
|
|
3299
|
+
addToCart: 'en' === language ? 'Add to cart' : 'Přidat do košíku',
|
|
3300
|
+
remove: 'en' === language ? 'Remove' : 'Odebrat',
|
|
3301
|
+
viewCart: 'en' === language ? 'View cart' : 'Zobrazit košík'
|
|
3302
|
+
},
|
|
3303
|
+
cart: {
|
|
3304
|
+
empty: 'en' === language ? 'Your cart is empty.' : 'Košík je prázdný.',
|
|
3305
|
+
title: 'en' === language ? 'Your cart' : 'Váš košík',
|
|
3306
|
+
total: 'en' === language ? 'Total' : 'Celkem'
|
|
3307
|
+
}
|
|
3308
|
+
} : {}
|
|
2816
3309
|
}
|
|
2817
3310
|
};
|
|
2818
3311
|
}
|
|
@@ -2846,6 +3339,102 @@ function createDesignTokens() {
|
|
|
2846
3339
|
} as const;
|
|
2847
3340
|
`;
|
|
2848
3341
|
}
|
|
3342
|
+
function createCheckoutCartStore() {
|
|
3343
|
+
return `import { useEffect, useMemo, useState } from 'react';
|
|
3344
|
+
|
|
3345
|
+
export type CartLine = {
|
|
3346
|
+
id: string;
|
|
3347
|
+
name: string;
|
|
3348
|
+
price: number;
|
|
3349
|
+
quantity: number;
|
|
3350
|
+
};
|
|
3351
|
+
|
|
3352
|
+
const storageKey = 'ultramodern-tractor-cart';
|
|
3353
|
+
const cartEvent = 'ultramodern-cart-change';
|
|
3354
|
+
const fieldLoader: CartLine = {
|
|
3355
|
+
id: 'field-loader-112',
|
|
3356
|
+
name: 'Field Loader 112',
|
|
3357
|
+
price: 42500,
|
|
3358
|
+
quantity: 1,
|
|
3359
|
+
};
|
|
3360
|
+
|
|
3361
|
+
const readCart = (): CartLine[] => {
|
|
3362
|
+
if (typeof window === 'undefined') {
|
|
3363
|
+
return [];
|
|
3364
|
+
}
|
|
3365
|
+
|
|
3366
|
+
try {
|
|
3367
|
+
const value = window.localStorage.getItem(storageKey);
|
|
3368
|
+
return value ? (JSON.parse(value) as CartLine[]) : [];
|
|
3369
|
+
} catch {
|
|
3370
|
+
return [];
|
|
3371
|
+
}
|
|
3372
|
+
};
|
|
3373
|
+
|
|
3374
|
+
const writeCart = (lines: CartLine[]) => {
|
|
3375
|
+
if (typeof window === 'undefined') {
|
|
3376
|
+
return;
|
|
3377
|
+
}
|
|
3378
|
+
|
|
3379
|
+
window.localStorage.setItem(storageKey, JSON.stringify(lines));
|
|
3380
|
+
window.dispatchEvent(new CustomEvent(cartEvent));
|
|
3381
|
+
};
|
|
3382
|
+
|
|
3383
|
+
const updateLine = (
|
|
3384
|
+
id: string,
|
|
3385
|
+
updater: (line: CartLine) => CartLine | undefined,
|
|
3386
|
+
) => {
|
|
3387
|
+
const next = readCart()
|
|
3388
|
+
.map(line => (line.id === id ? updater(line) : line))
|
|
3389
|
+
.filter((line): line is CartLine => Boolean(line));
|
|
3390
|
+
writeCart(next);
|
|
3391
|
+
};
|
|
3392
|
+
|
|
3393
|
+
export function useCartLines() {
|
|
3394
|
+
const [lines, setLines] = useState<CartLine[]>(() => readCart());
|
|
3395
|
+
|
|
3396
|
+
useEffect(() => {
|
|
3397
|
+
const refresh = () => setLines(readCart());
|
|
3398
|
+
window.addEventListener(cartEvent, refresh);
|
|
3399
|
+
window.addEventListener('storage', refresh);
|
|
3400
|
+
refresh();
|
|
3401
|
+
|
|
3402
|
+
return () => {
|
|
3403
|
+
window.removeEventListener(cartEvent, refresh);
|
|
3404
|
+
window.removeEventListener('storage', refresh);
|
|
3405
|
+
};
|
|
3406
|
+
}, []);
|
|
3407
|
+
|
|
3408
|
+
return useMemo(
|
|
3409
|
+
() => ({
|
|
3410
|
+
lines,
|
|
3411
|
+
total: lines.reduce((sum, line) => sum + line.price * line.quantity, 0),
|
|
3412
|
+
addFieldLoader: () => {
|
|
3413
|
+
const existing = readCart();
|
|
3414
|
+
const match = existing.find(line => line.id === fieldLoader.id);
|
|
3415
|
+
writeCart(
|
|
3416
|
+
match
|
|
3417
|
+
? existing.map(line =>
|
|
3418
|
+
line.id === fieldLoader.id
|
|
3419
|
+
? { ...line, quantity: line.quantity + 1 }
|
|
3420
|
+
: line,
|
|
3421
|
+
)
|
|
3422
|
+
: [...existing, fieldLoader],
|
|
3423
|
+
);
|
|
3424
|
+
},
|
|
3425
|
+
increment: (id: string) =>
|
|
3426
|
+
updateLine(id, line => ({ ...line, quantity: line.quantity + 1 })),
|
|
3427
|
+
decrement: (id: string) =>
|
|
3428
|
+
updateLine(id, line =>
|
|
3429
|
+
line.quantity > 1 ? { ...line, quantity: line.quantity - 1 } : undefined,
|
|
3430
|
+
),
|
|
3431
|
+
remove: (id: string) => writeCart(readCart().filter(line => line.id !== id)),
|
|
3432
|
+
}),
|
|
3433
|
+
[lines],
|
|
3434
|
+
);
|
|
3435
|
+
}
|
|
3436
|
+
`;
|
|
3437
|
+
}
|
|
2849
3438
|
function createSharedDesignTokensCss() {
|
|
2850
3439
|
return `@layer ultramodern-shared-tokens {
|
|
2851
3440
|
:root {
|
|
@@ -4715,8 +5304,23 @@ function writeApp(targetDir, scope, app, packageSource, enableTailwind) {
|
|
|
4715
5304
|
writeFile(targetDir, `${app.directory}/module-federation.config.ts`, 'shell' === app.kind ? createShellModuleFederationConfig() : createRemoteModuleFederationConfig(app));
|
|
4716
5305
|
writeFile(targetDir, `${app.directory}/src/routes/layout.tsx`, createLayout(app.id));
|
|
4717
5306
|
writeFile(targetDir, `${app.directory}/src/routes/[lang]/page.tsx`, 'shell' === app.kind ? createShellPage() : createRemotePage(app));
|
|
4718
|
-
for (const route of createRouteOwnedI18nPaths(app))
|
|
4719
|
-
|
|
5307
|
+
for (const route of createRouteOwnedI18nPaths(app)){
|
|
5308
|
+
if ('/' === route.canonicalPath || 'shell' === app.kind) continue;
|
|
5309
|
+
const routePaths = new Set([
|
|
5310
|
+
route.canonicalPath,
|
|
5311
|
+
...Object.values(route.localisedPaths)
|
|
5312
|
+
]);
|
|
5313
|
+
for (const routePath of routePaths)if ('/' !== routePath) writeFile(targetDir, createRoutePageFilePath(app, routePath), createRouteAliasPage(routePath));
|
|
5314
|
+
}
|
|
5315
|
+
if ('shell' === app.kind) {
|
|
5316
|
+
writeFile(targetDir, `${app.directory}/src/effect/recommendations-client.ts`, createShellEffectClient(scope));
|
|
5317
|
+
writeFile(targetDir, `${app.directory}/src/routes/[lang]/tractors/page.tsx`, createShellTractorsPage());
|
|
5318
|
+
writeFile(targetDir, `${app.directory}/src/routes/[lang]/traktory/page.tsx`, createShellTractorsPage());
|
|
5319
|
+
writeFile(targetDir, `${app.directory}/src/routes/[lang]/tractors/[slug]/page.tsx`, createShellProductPage());
|
|
5320
|
+
writeFile(targetDir, `${app.directory}/src/routes/[lang]/traktory/[slug]/page.tsx`, createShellProductPage());
|
|
5321
|
+
writeFile(targetDir, `${app.directory}/src/routes/[lang]/cart/page.tsx`, createShellCartPage());
|
|
5322
|
+
writeFile(targetDir, `${app.directory}/src/routes/[lang]/kosik/page.tsx`, createShellCartPage());
|
|
5323
|
+
}
|
|
4720
5324
|
if (appHasEffectApi(app)) {
|
|
4721
5325
|
writeFile(targetDir, `${app.directory}/shared/effect/api.ts`, createEffectSharedApi(app));
|
|
4722
5326
|
writeFile(targetDir, `${app.directory}/api/effect/index.ts`, createEffectServiceEntry(scope, app, '../../shared/effect/api'));
|
|
@@ -4724,6 +5328,7 @@ function writeApp(targetDir, scope, app, packageSource, enableTailwind) {
|
|
|
4724
5328
|
}
|
|
4725
5329
|
if ('vertical' === app.kind || 'horizontal-remote' === app.kind) {
|
|
4726
5330
|
writeFile(targetDir, `${app.directory}/src/remote-entry.tsx`, createRemoteEntry(app));
|
|
5331
|
+
if ('remote-checkout' === app.id) writeFile(targetDir, `${app.directory}/src/cart-store.ts`, createCheckoutCartStore());
|
|
4727
5332
|
for (const expose of Object.keys(app.exposes ?? {})){
|
|
4728
5333
|
const outputPath = remoteComponentOutputPath(app, expose);
|
|
4729
5334
|
if (outputPath) writeFile(targetDir, outputPath, createRemoteExposeComponent(app, expose));
|
package/package.json
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"engines": {
|
|
22
22
|
"node": ">=20"
|
|
23
23
|
},
|
|
24
|
-
"version": "3.2.0-ultramodern.
|
|
24
|
+
"version": "3.2.0-ultramodern.36",
|
|
25
25
|
"types": "./dist/types/index.d.ts",
|
|
26
26
|
"main": "./dist/index.js",
|
|
27
27
|
"bin": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@types/node": "^25.9.1",
|
|
42
42
|
"@typescript/native-preview": "7.0.0-dev.20260527.2",
|
|
43
43
|
"tsx": "^4.22.3",
|
|
44
|
-
"@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.
|
|
44
|
+
"@modern-js/i18n-utils": "npm:@bleedingdev/modern-js-i18n-utils@3.2.0-ultramodern.36"
|
|
45
45
|
},
|
|
46
46
|
"publishConfig": {
|
|
47
47
|
"registry": "https://registry.npmjs.org/",
|
|
@@ -54,6 +54,6 @@
|
|
|
54
54
|
"start": "node ./dist/index.js"
|
|
55
55
|
},
|
|
56
56
|
"ultramodern": {
|
|
57
|
-
"frameworkVersion": "3.2.0-ultramodern.
|
|
57
|
+
"frameworkVersion": "3.2.0-ultramodern.36"
|
|
58
58
|
}
|
|
59
59
|
}
|