@akinon/projectzero 1.106.0-rc.85 → 1.106.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.
Files changed (34) hide show
  1. package/CHANGELOG.md +6 -230
  2. package/app-template/.env.example +0 -1
  3. package/app-template/CHANGELOG.md +329 -4945
  4. package/app-template/README.md +1 -25
  5. package/app-template/package.json +20 -20
  6. package/app-template/public/locales/en/common.json +1 -42
  7. package/app-template/public/locales/tr/common.json +1 -42
  8. package/app-template/src/app/[commerce]/[locale]/[currency]/basket/page.tsx +82 -9
  9. package/app-template/src/app/[commerce]/[locale]/[currency]/landing-page/[pk]/page.tsx +1 -12
  10. package/app-template/src/assets/fonts/pz-icon.css +0 -3
  11. package/app-template/src/components/input.tsx +1 -2
  12. package/app-template/src/hooks/index.ts +0 -2
  13. package/app-template/src/plugins.js +1 -2
  14. package/app-template/src/settings.js +1 -6
  15. package/app-template/src/views/basket/basket-item.tsx +13 -16
  16. package/app-template/src/views/basket/summary.tsx +7 -10
  17. package/app-template/src/views/guest-login/index.tsx +1 -6
  18. package/app-template/src/views/header/search/index.tsx +5 -17
  19. package/app-template/src/views/product/product-info.tsx +263 -61
  20. package/app-template/src/views/product/slider.tsx +73 -86
  21. package/commands/plugins.ts +2 -29
  22. package/dist/commands/plugins.js +2 -23
  23. package/package.json +1 -1
  24. package/app-template/src/app/[commerce]/[locale]/[currency]/product/[pk]/loading.tsx +0 -67
  25. package/app-template/src/app/api/image-proxy/route.ts +0 -1
  26. package/app-template/src/app/api/similar-product-list/route.ts +0 -1
  27. package/app-template/src/app/api/similar-products/route.ts +0 -1
  28. package/app-template/src/hooks/use-product-cart.ts +0 -77
  29. package/app-template/src/hooks/use-stock-alert.ts +0 -74
  30. package/app-template/src/utils/variant-validation.ts +0 -41
  31. package/app-template/src/views/basket/basket-content.tsx +0 -106
  32. package/app-template/src/views/product/product-actions.tsx +0 -165
  33. package/app-template/src/views/product/product-share.tsx +0 -56
  34. package/app-template/src/views/product/product-variants.tsx +0 -26
@@ -1,73 +1,178 @@
1
1
  'use client';
2
2
 
3
3
  import clsx from 'clsx';
4
+ import { Button, Icon, Modal } from '@theme/components';
5
+ import { useAddProductToBasket } from '../../hooks';
4
6
  import React, { useEffect, useState } from 'react';
5
- import { PriceWrapper } from '@theme/views/product';
7
+ import { useAddStockAlertMutation } from '@akinon/next/data/client/wishlist';
8
+ import { pushAddToCart, pushProductViewed } from '@theme/utils/gtm';
9
+ import { PriceWrapper, Variant } from '@theme/views/product';
10
+ import Share from '@theme/views/share';
6
11
  import { ProductPageProps } from './layout';
7
12
  import MiscButtons from './misc-buttons';
8
- import { pushProductViewed } from '@theme/utils/gtm';
13
+ import { useLocalization } from '@akinon/next/hooks';
14
+ import PluginModule, { Component } from '@akinon/next/components/plugin-module';
15
+ import { Trans } from '@akinon/next/components/trans';
9
16
  import { useSession } from 'next-auth/react';
10
- import { isVariantSelectionComplete } from '../../utils/variant-validation';
11
- import { useProductCart } from '../../hooks/use-product-cart';
12
- import { useStockAlert } from '../../hooks/use-stock-alert';
13
- import { ProductVariants } from './product-variants';
14
- import { ProductActions } from './product-actions';
15
- import { ProductShare } from './product-share';
16
17
 
17
18
  export default function ProductInfo({ data }: ProductPageProps) {
19
+ const { t } = useLocalization();
18
20
  const { data: session } = useSession();
21
+ const [currentUrl, setCurrentUrl] = useState(null);
22
+ const [productError, setProductError] = useState(null);
23
+ const [isModalOpen, setIsModalOpen] = useState(false);
24
+ const [stockAlertResponseMessage, setStockAlertResponseMessage] =
25
+ useState(null);
19
26
  const [isVariantLoading, setIsVariantLoading] = useState(false);
20
27
 
28
+ const [addProduct, { isLoading: isAddToCartLoading }] =
29
+ useAddProductToBasket();
30
+ const [addStockAlert, { isLoading: isAddToStockAlertLoading }] =
31
+ useAddStockAlertMutation();
21
32
  const inStock = data.selected_variant !== null || data.product.in_stock;
22
33
 
23
- const {
24
- addProductToCart,
25
- productError: cartError,
26
- clearProductError: clearCartError,
27
- isAddToCartLoading
28
- } = useProductCart({
29
- product: data.product,
30
- variants: data.variants
31
- });
32
-
33
- const {
34
- addProductToStockAlertList,
35
- isModalOpen,
36
- stockAlertResponseMessage,
37
- productError: stockError,
38
- isAddToStockAlertLoading,
39
- closeModal,
40
- clearError: clearStockError
41
- } = useStockAlert({
42
- productPk: data.product.pk,
43
- userEmail: session?.user?.email
44
- });
45
-
46
- const productError = cartError || stockError;
47
- const clearProductError = () => {
48
- clearCartError();
49
- clearStockError();
50
- };
51
-
52
34
  useEffect(() => {
53
- isVariantSelectionComplete(data.variants) && setIsVariantLoading(false);
35
+ isVariantSelectionComplete() && setIsVariantLoading(false);
36
+
54
37
  !inStock && setIsVariantLoading(false);
55
- }, [data, inStock]);
38
+ }, [data]); // eslint-disable-line react-hooks/exhaustive-deps
56
39
 
57
40
  useEffect(() => {
58
41
  if (isVariantLoading) {
59
- clearProductError();
42
+ setProductError(null);
60
43
  }
61
44
  // eslint-disable-next-line react-hooks/exhaustive-deps
62
45
  }, [isVariantLoading]);
63
46
 
47
+ useEffect(() => {
48
+ setCurrentUrl(window.location.href);
49
+ }, [currentUrl]);
50
+
64
51
  useEffect(() => {
65
52
  pushProductViewed(data?.product);
66
53
  }, []); // eslint-disable-line react-hooks/exhaustive-deps
67
54
 
68
- const handleVariantChange = () => {
69
- clearProductError();
70
- setIsVariantLoading(true);
55
+ const addProductToCart = async () => {
56
+ if (!variantsSelectionCheck()) {
57
+ return;
58
+ }
59
+
60
+ try {
61
+ await addProduct({
62
+ product: data.product.pk,
63
+ quantity: 1,
64
+ attributes: {}
65
+ });
66
+
67
+ pushAddToCart(data?.product);
68
+ } catch (error) {
69
+ setProductError(
70
+ error?.data?.non_field_errors ||
71
+ Object.keys(error?.data).map(
72
+ (key) => `${key}: ${error?.data[key].join(', ')}`
73
+ )
74
+ );
75
+ }
76
+ };
77
+
78
+ const variantsSelectionCheck = () => {
79
+ const unselectedVariant = data.variants.find((variant) =>
80
+ variant.options.every((opt) => !opt.is_selected)
81
+ );
82
+
83
+ if (unselectedVariant) {
84
+ setProductError(() => (
85
+ <Trans
86
+ i18nKey="product.please_select_variant"
87
+ components={{
88
+ VariantName: <span>{unselectedVariant.attribute_name}</span>
89
+ }}
90
+ />
91
+ ));
92
+
93
+ return false;
94
+ }
95
+
96
+ return true;
97
+ };
98
+
99
+ const isVariantSelectionComplete = () => {
100
+ return data?.variants.every((variant) =>
101
+ variant?.options.some((opt) => opt.is_selected)
102
+ );
103
+ };
104
+
105
+ const addProductToStockAlertList = async () => {
106
+ try {
107
+ await addStockAlert({
108
+ productPk: data.product.pk,
109
+ email: session?.user?.email
110
+ })
111
+ .unwrap()
112
+ .then(handleSuccess)
113
+ .catch((err) => handleError(err));
114
+ } catch (error) {
115
+ setProductError(error?.data?.non_field_errors || null);
116
+ }
117
+ };
118
+
119
+ const handleModalClick = () => {
120
+ setIsModalOpen(false);
121
+ };
122
+
123
+ const handleSuccess = () => {
124
+ setStockAlertResponseMessage(() => (
125
+ <Trans
126
+ i18nKey="product.stock_alert.success_description"
127
+ components={{
128
+ Email: <span>{session?.user?.email}</span>
129
+ }}
130
+ />
131
+ ));
132
+ setIsModalOpen(true);
133
+ };
134
+
135
+ const handleError = (err) => {
136
+ if (err.status !== 401) {
137
+ setStockAlertResponseMessage(
138
+ t('product.stock_alert.error_description').toString()
139
+ );
140
+ setIsModalOpen(true);
141
+ }
142
+ };
143
+
144
+ const checkoutProviderProps = {
145
+ product: data.product,
146
+ clearBasket: true,
147
+ addBeforeClick: variantsSelectionCheck,
148
+ openMiniBasket: false,
149
+ className: clsx([
150
+ 'py-2.5',
151
+ 'bg-black',
152
+ 'relative',
153
+ 'hover:bg-black',
154
+ 'before:content-[""]',
155
+ 'before:w-6',
156
+ 'before:h-6',
157
+ 'before:bg-white',
158
+ 'before:absolute',
159
+ 'before:rounded-r-[18px]',
160
+ 'before:left-0',
161
+ 'after:content-[""]',
162
+ 'after:absolute',
163
+ 'after:w-3',
164
+ 'after:h-3',
165
+ 'after:bg-[#d02c2f]',
166
+ 'after:rounded-xl',
167
+ 'after:left-1'
168
+ ]),
169
+ onError: (error) =>
170
+ setProductError(
171
+ error?.data?.non_field_errors ||
172
+ Object.keys(error?.data).map(
173
+ (key) => `${key}: ${error?.data[key].join(', ')}`
174
+ )
175
+ )
71
176
  };
72
177
 
73
178
  return (
@@ -83,26 +188,72 @@ export default function ProductInfo({ data }: ProductPageProps) {
83
188
  retailPrice={data.product.retail_price}
84
189
  />
85
190
  </div>
191
+ <div className="flex flex-col">
192
+ {data.variants.map((variant) => (
193
+ <Variant
194
+ key={variant.attribute_key}
195
+ {...variant}
196
+ className="items-center mt-8"
197
+ onChange={() => {
198
+ setProductError(null);
199
+ setIsVariantLoading(true);
200
+ }}
201
+ />
202
+ ))}
203
+ </div>
86
204
 
87
- <ProductVariants
88
- variants={data.variants}
89
- onVariantChange={handleVariantChange}
205
+ {productError && (
206
+ <div className="mt-4 text-xs text-center text-error">
207
+ {productError}
208
+ </div>
209
+ )}
210
+
211
+ <Button
212
+ disabled={
213
+ isAddToCartLoading || isAddToStockAlertLoading || isVariantLoading
214
+ }
215
+ className={clsx(
216
+ 'fixed bottom-0 right-0 w-1/2 h-14 z-[20] flex items-center justify-center fill-primary-foreground',
217
+ 'hover:fill-primary sm:relative sm:w-full sm:mt-3 sm:font-semibold sm:h-12'
218
+ )}
219
+ onClick={() => {
220
+ setProductError(null);
221
+
222
+ if (inStock) {
223
+ addProductToCart();
224
+ } else {
225
+ addProductToStockAlertList();
226
+ }
227
+ }}
228
+ data-testid="product-add-to-cart"
229
+ >
230
+ {isVariantLoading ? (
231
+ <Icon
232
+ name="spinner"
233
+ size={20}
234
+ className="animate-spin mr-4 fill-primary"
235
+ />
236
+ ) : inStock ? (
237
+ <span>{t('product.add_to_cart')}</span>
238
+ ) : (
239
+ <>
240
+ <Icon name="bell" size={20} className="mr-4" />
241
+ <span>{t('product.add_stock_alert')}</span>
242
+ </>
243
+ )}
244
+ </Button>
245
+
246
+ <PluginModule
247
+ component={Component.AkifastCheckoutButton}
248
+ props={{
249
+ ...checkoutProviderProps,
250
+ isPdp: true
251
+ }}
90
252
  />
91
253
 
92
- <ProductActions
93
- product={data.product}
94
- variants={data.variants}
95
- inStock={inStock}
96
- isVariantLoading={isVariantLoading}
97
- onAddToCart={addProductToCart}
98
- onAddToStockAlert={addProductToStockAlertList}
99
- onClearError={clearProductError}
100
- isAddToCartLoading={isAddToCartLoading}
101
- isAddToStockAlertLoading={isAddToStockAlertLoading}
102
- productError={productError}
103
- isModalOpen={isModalOpen}
104
- stockAlertResponseMessage={stockAlertResponseMessage}
105
- onCloseModal={closeModal}
254
+ <PluginModule
255
+ component={Component.OneClickCheckoutButtons}
256
+ props={checkoutProviderProps}
106
257
  />
107
258
 
108
259
  <MiscButtons
@@ -111,7 +262,58 @@ export default function ProductInfo({ data }: ProductPageProps) {
111
262
  variants={data.variants}
112
263
  />
113
264
 
114
- <ProductShare productName={data.product.name} className="my-2 sm:mb-4" />
265
+ <Share
266
+ className="my-2 sm:mb-4"
267
+ buttonText={t('product.share')}
268
+ items={[
269
+ {
270
+ href: `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(
271
+ currentUrl
272
+ )}`,
273
+ iconName: 'facebook',
274
+ iconSize: 22
275
+ },
276
+ {
277
+ href: `https://twitter.com/intent/tweet?text=${encodeURIComponent(
278
+ currentUrl
279
+ )}`,
280
+ iconName: 'twitter',
281
+ iconSize: 22
282
+ },
283
+ {
284
+ href: `https://api.whatsapp.com/send?text=${
285
+ data.product.name
286
+ }%20${encodeURIComponent(currentUrl)}`,
287
+ iconName: 'whatsapp',
288
+ iconSize: 22
289
+ }
290
+ ]}
291
+ />
292
+
293
+ <Modal
294
+ portalId="stock-alert-modal"
295
+ open={isModalOpen}
296
+ setOpen={setIsModalOpen}
297
+ showCloseButton={false}
298
+ className="w-5/6 md:max-w-md"
299
+ >
300
+ <div className="flex flex-col items-center justify-center gap-4 px-6 py-9">
301
+ <Icon name="bell" size={48} />
302
+ <h2 className="text-xl font-semibold">
303
+ {t('product.stock_alert.title')}
304
+ </h2>
305
+ <div className="max-w-40 text-xs text-center leading-4">
306
+ <p>{stockAlertResponseMessage}</p>
307
+ </div>
308
+ <Button
309
+ onClick={handleModalClick}
310
+ appearance="outlined"
311
+ className="font-semibold px-10 h-12"
312
+ >
313
+ {t('product.stock_alert.close_button')}
314
+ </Button>
315
+ </div>
316
+ </Modal>
115
317
  </>
116
318
  );
117
319
  }
@@ -7,7 +7,6 @@ import { Product } from '@akinon/next/types';
7
7
  import { Image } from '@akinon/next/components/image';
8
8
  import useFavButton from '../../hooks/use-fav-button';
9
9
  import { twMerge } from 'tailwind-merge';
10
- import PluginModule, { Component } from '@akinon/next/components/plugin-module';
11
10
 
12
11
  type ProductSliderItem = {
13
12
  product: Product;
@@ -36,102 +35,90 @@ export default function ProductInfoSlider({ product }: ProductSliderItem) {
36
35
  carouselRef.current?.next();
37
36
  };
38
37
 
39
- const handleThumbnailClick = (index: number) => {
38
+ const handleThumbnailClick = (index) => {
40
39
  setActiveIndex(index);
41
40
  carouselRef.current?.goToSlide(index);
42
41
  };
43
42
 
44
43
  return (
45
- <>
46
- <div className="lg:grid lg:grid-cols-6">
47
- <div className="lg:col-span-1">
48
- <div className="flex flex-col items-center justify-center md:mr-[6px]">
49
- <button
50
- onClick={goToPrev}
51
- className={twMerge(
52
- 'hidden justify-center p-2 mb-3 border border-gray-100 rounded-full cursor-pointer lg:block',
53
- [activeIndex === 0 && 'cursor-not-allowed opacity-45']
54
- )}
55
- disabled={activeIndex === 0}
56
- >
57
- <Icon name="chevron-up" size={15} className="fill-[#000000]" />
58
- </button>
59
- <div className="hidden flex-col items-center overflow-scroll w-[80px] max-h-[620px] lg:block">
60
- {product?.productimage_set?.map((item, index) => (
61
- <Image
62
- key={index}
63
- src={item.image}
64
- alt={`Thumbnail ${index}`}
65
- width={80}
66
- height={128}
67
- aspectRatio={80 / 128}
68
- className={twMerge('cursor-pointer', [
69
- activeIndex === index && 'border-2 border-primary'
70
- ])}
71
- onClick={() => handleThumbnailClick(index)}
72
- />
73
- ))}
74
- </div>
75
- <button
76
- onClick={goToNext}
77
- className={twMerge(
78
- 'hidden justify-center p-2 mt-3 border border-gray-100 rounded-full cursor-pointer lg:block',
79
- [
80
- activeIndex === product.productimage_set.length - 1 &&
81
- 'cursor-not-allowed opacity-45'
82
- ]
83
- )}
84
- disabled={activeIndex === product.productimage_set.length - 1}
85
- >
86
- <Icon name="chevron-down" size={15} className="fill-[#000000]" />
87
- </button>
88
- </div>
89
- </div>
90
-
91
- <div className="relative lg:col-span-5">
92
- <FavButton className="absolute right-8 top-6 z-[20] sm:hidden" />
93
-
94
- <PluginModule
95
- component={Component.ProductImageSearchFeature}
96
- props={{
97
- product,
98
- activeIndex,
99
- showResetButton: true
100
- }}
101
- />
102
-
103
- <CarouselCore
104
- responsive={{
105
- all: {
106
- breakpoint: { max: 5000, min: 0 },
107
- items: 1
108
- }
109
- }}
110
- arrows={false}
111
- swipeable={true}
112
- ref={carouselRef}
113
- afterChange={(previousSlide, { currentSlide }) => {
114
- setActiveIndex(currentSlide);
115
- }}
116
- containerAspectRatio={{ mobile: 520 / 798, desktop: 484 / 726 }}
44
+ <div className="lg:grid lg:grid-cols-6">
45
+ <div className="lg:col-span-1">
46
+ <div className="flex flex-col items-center justify-center md:mr-[6px]">
47
+ <button
48
+ onClick={goToPrev}
49
+ className={twMerge(
50
+ 'hidden justify-center p-2 mb-3 border border-gray-100 rounded-full cursor-pointer lg:block',
51
+ [activeIndex === 0 && 'cursor-not-allowed opacity-45']
52
+ )}
53
+ disabled={activeIndex === 0}
117
54
  >
118
- {product?.productimage_set?.map((item, i) => (
55
+ <Icon name="chevron-up" size={15} className="fill-[#000000]" />
56
+ </button>
57
+ <div className="hidden flex-col items-center overflow-scroll w-[80px] max-h-[620px] lg:block">
58
+ {product?.productimage_set?.map((item, index) => (
119
59
  <Image
120
- key={i}
60
+ key={index}
121
61
  src={item.image}
122
- alt={product?.name || 'Product image'}
123
- draggable={false}
124
- aspectRatio={484 / 726}
125
- sizes="(min-width: 425px) 512px,
126
- (min-width: 601px) 576px,
127
- (min-width: 768px) 336px,
128
- (min-width: 1024px) 484px, 368px"
129
- fill
62
+ alt={`Thumbnail ${index}`}
63
+ width={80}
64
+ height={128}
65
+ className={twMerge('cursor-pointer', [
66
+ activeIndex === index && 'border-2 border-primary'
67
+ ])}
68
+ onClick={() => handleThumbnailClick(index)}
130
69
  />
131
70
  ))}
132
- </CarouselCore>
71
+ </div>
72
+ <button
73
+ onClick={goToNext}
74
+ className={twMerge(
75
+ 'hidden justify-center p-2 mt-3 border border-gray-100 rounded-full cursor-pointer lg:block',
76
+ [
77
+ activeIndex === product.productimage_set.length - 1 &&
78
+ 'cursor-not-allowed opacity-45'
79
+ ]
80
+ )}
81
+ disabled={activeIndex === product.productimage_set.length - 1}
82
+ >
83
+ <Icon name="chevron-down" size={15} className="fill-[#000000]" />
84
+ </button>
133
85
  </div>
134
86
  </div>
135
- </>
87
+
88
+ <div className="relative lg:col-span-5">
89
+ <FavButton className="absolute right-8 top-6 z-[20] sm:hidden" />
90
+
91
+ <CarouselCore
92
+ responsive={{
93
+ all: {
94
+ breakpoint: { max: 5000, min: 0 },
95
+ items: 1
96
+ }
97
+ }}
98
+ arrows={false}
99
+ swipeable={true}
100
+ ref={carouselRef}
101
+ afterChange={(previousSlide, { currentSlide }) => {
102
+ setActiveIndex(currentSlide);
103
+ }}
104
+ containerAspectRatio={{ mobile: 520 / 798, desktop: 484 / 726 }}
105
+ >
106
+ {product?.productimage_set?.map((item, i) => (
107
+ <Image
108
+ key={i}
109
+ src={item.image}
110
+ alt={product.name}
111
+ draggable={false}
112
+ aspectRatio={484 / 726}
113
+ sizes="(min-width: 425px) 512px,
114
+ (min-width: 601px) 576px,
115
+ (min-width: 768px) 336px,
116
+ (min-width: 1024px) 484px, 368px"
117
+ fill
118
+ />
119
+ ))}
120
+ </CarouselCore>
121
+ </div>
122
+ </div>
136
123
  );
137
124
  }
@@ -29,14 +29,7 @@ async function checkVersion(pkg: PackageJson) {
29
29
 
30
30
  if (!semver.satisfies(pkg.dependencies['@akinon/next'], latestVersion)) {
31
31
  console.warn(
32
- `\x1b[43m Warning: The "${packageName}" package is currently at`,
33
- `\x1b[41m version ${pkg.dependencies['@akinon/next']}`,
34
- `\x1b[43m Please upgrade it to the latest version (${latestVersion}) to ensure plugin compatibility.`,
35
- '\x1b[0m\n'
36
- );
37
- } else {
38
- console.log(
39
- `\x1b[42m Info: The package "${packageName}" is currently in the current version (${latestVersion}).`,
32
+ `\x1b[43mWarning: The "${packageName}" package is currently at version ${pkg.dependencies['@akinon/next']}. Please upgrade it to the latest version (${latestVersion}) to ensure plugin compatibility.`,
40
33
  '\x1b[0m\n'
41
34
  );
42
35
  }
@@ -61,27 +54,7 @@ export default async () => {
61
54
  }
62
55
  }
63
56
 
64
- function findPackageJson(): PackageJson {
65
- const packageJsonPaths = [
66
- path.resolve(rootDir, './package.json'),
67
- path.resolve(rootDir, './apps/projectzeronext/package.json')
68
- ];
69
-
70
- for (const packageJsonPath of packageJsonPaths) {
71
- try {
72
- const pkg = require(packageJsonPath);
73
- if (pkg.dependencies['@akinon/next']) {
74
- return pkg;
75
- }
76
- } catch (error) {
77
- continue;
78
- }
79
- }
80
-
81
- throw new Error('Could not find package.json with @akinon/next dependency');
82
- }
83
-
84
- const pkg = findPackageJson();
57
+ const pkg: PackageJson = require(path.resolve(rootDir, './package.json'));
85
58
  await checkVersion(pkg);
86
59
 
87
60
  const pluginsFilePath = findPluginsFilePath();
@@ -50,10 +50,7 @@ function checkVersion(pkg) {
50
50
  const pkgInfo = (yield response.json());
51
51
  const latestVersion = pkgInfo['dist-tags'].latest;
52
52
  if (!semver_1.default.satisfies(pkg.dependencies['@akinon/next'], latestVersion)) {
53
- console.warn(`\x1b[43m Warning: The "${packageName}" package is currently at`, `\x1b[41m version ${pkg.dependencies['@akinon/next']}`, `\x1b[43m Please upgrade it to the latest version (${latestVersion}) to ensure plugin compatibility.`, '\x1b[0m\n');
54
- }
55
- else {
56
- console.log(`\x1b[42m Info: The package "${packageName}" is currently in the current version (${latestVersion}).`, '\x1b[0m\n');
53
+ console.warn(`\x1b[43mWarning: The "${packageName}" package is currently at version ${pkg.dependencies['@akinon/next']}. Please upgrade it to the latest version (${latestVersion}) to ensure plugin compatibility.`, '\x1b[0m\n');
57
54
  }
58
55
  }
59
56
  catch (error) {
@@ -75,25 +72,7 @@ exports.default = () => __awaiter(void 0, void 0, void 0, function* () {
75
72
  throw new Error('plugins.js was not found in either of the expected locations.');
76
73
  }
77
74
  }
78
- function findPackageJson() {
79
- const packageJsonPaths = [
80
- path_1.default.resolve(rootDir, './package.json'),
81
- path_1.default.resolve(rootDir, './apps/projectzeronext/package.json')
82
- ];
83
- for (const packageJsonPath of packageJsonPaths) {
84
- try {
85
- const pkg = require(packageJsonPath);
86
- if (pkg.dependencies['@akinon/next']) {
87
- return pkg;
88
- }
89
- }
90
- catch (error) {
91
- continue;
92
- }
93
- }
94
- throw new Error('Could not find package.json with @akinon/next dependency');
95
- }
96
- const pkg = findPackageJson();
75
+ const pkg = require(path_1.default.resolve(rootDir, './package.json'));
97
76
  yield checkVersion(pkg);
98
77
  const pluginsFilePath = findPluginsFilePath();
99
78
  let installedPlugins = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akinon/projectzero",
3
- "version": "1.106.0-rc.85",
3
+ "version": "1.106.0",
4
4
  "private": false,
5
5
  "description": "CLI tool to manage your Project Zero Next project",
6
6
  "bin": {