@akinon/projectzero 2.0.0-beta.10 → 2.0.0-beta.12

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.
@@ -22,14 +22,15 @@ export const AnonymousTrackingOrderDetail = ({ order }) => {
22
22
  const groupedOrder = [];
23
23
 
24
24
  if (order) {
25
- const groupedData = order.orderitem_set.reduce((groups, item) => {
26
- const { tracking_number } = item;
27
- if (!groups[tracking_number]) {
28
- groups[tracking_number] = [];
29
- }
30
- groups[tracking_number].push(item);
31
- return groups;
32
- }, {});
25
+ const groupedData =
26
+ order?.orderitem_set?.reduce((groups, item) => {
27
+ const { tracking_number } = item;
28
+ if (!groups[tracking_number]) {
29
+ groups[tracking_number] = [];
30
+ }
31
+ groups[tracking_number].push(item);
32
+ return groups;
33
+ }, {}) || {};
33
34
 
34
35
  const result = Object.values(groupedData);
35
36
 
@@ -67,8 +68,8 @@ export const AnonymousTrackingOrderDetail = ({ order }) => {
67
68
 
68
69
  <div>
69
70
  <span className="text-base font-bold">
70
- {order.orderitem_set.length}{' '}
71
- {t('account.my_orders.detail.products')} {groupedOrder.length}{' '}
71
+ {order?.orderitem_set?.length}{' '}
72
+ {t('account.my_orders.detail.products')} {groupedOrder?.length}{' '}
72
73
  {t('account.my_orders.detail.packages')}
73
74
  </span>
74
75
  </div>
@@ -78,17 +79,17 @@ export const AnonymousTrackingOrderDetail = ({ order }) => {
78
79
  className="break-words"
79
80
  >
80
81
  <span>{t('account.my_orders.detail.delivery_address')}</span>:{' '}
81
- {order?.shipping_address.line}{' '}
82
- {order?.shipping_address.district.name}{' '}
83
- {order?.shipping_address.township.name}{' '}
84
- {order?.shipping_address.city.name}
82
+ {order?.shipping_address?.line}{' '}
83
+ {order?.shipping_address?.district?.name}{' '}
84
+ {order?.shipping_address?.township?.name}{' '}
85
+ {order?.shipping_address?.city?.name}
85
86
  </div>
86
87
  </OrderDetailHeader>
87
88
 
88
89
  <div>
89
90
  {groupedOrder.map((group, i) => {
90
91
  const orderStatus = getOrderStatus(
91
- group[0].status.value.toString(),
92
+ group[0]?.status?.value?.toString(),
92
93
  t
93
94
  );
94
95
 
@@ -112,8 +113,8 @@ export const AnonymousTrackingOrderDetail = ({ order }) => {
112
113
  <div className="flex justify-between items-center lg:gap-x-12">
113
114
  <div className="text-base">{orderStatus.label}</div>
114
115
 
115
- {group[0].tracking_number && group[0].tracking_url && (
116
- <Link href={group[0].tracking_url}>
116
+ {group[0]?.tracking_number && group[0]?.tracking_url && (
117
+ <Link href={group[0]?.tracking_url}>
117
118
  <Button className="px-7" appearance="filled">
118
119
  {t('account.my_orders.detail.track_shipment')}
119
120
  </Button>
@@ -125,7 +126,7 @@ export const AnonymousTrackingOrderDetail = ({ order }) => {
125
126
  <div className="px-4 lg:px-7">
126
127
  {group.map((item, index) => {
127
128
  const itemStatus = getOrderStatus(
128
- item.status.value.toString(),
129
+ item?.status?.value?.toString(),
129
130
  t
130
131
  );
131
132
 
@@ -138,15 +139,15 @@ export const AnonymousTrackingOrderDetail = ({ order }) => {
138
139
  <div className="shrink-0">
139
140
  <Link
140
141
  className="block"
141
- href={item.product.absolute_url}
142
+ href={item?.product?.absolute_url}
142
143
  >
143
144
  <Image
144
145
  src={
145
- item.product.image
146
+ item?.product?.image
146
147
  ? item.product.image
147
148
  : '/noimage.jpg'
148
149
  }
149
- alt={item.product.name}
150
+ alt={item?.product?.name}
150
151
  width={112}
151
152
  height={150}
152
153
  />
@@ -155,27 +156,32 @@ export const AnonymousTrackingOrderDetail = ({ order }) => {
155
156
 
156
157
  <div className="flex flex-col justify-between lg:max-w-48">
157
158
  <div className="text-sm">
158
- <Link href={item.product.absolute_url}>
159
- {item.product.name}
159
+ <Link href={item?.product?.absolute_url}>
160
+ {item?.product?.name}
160
161
  </Link>
161
162
  </div>
162
163
 
163
164
  <div className="text-gray-900 text-xs">
164
- {item.product.attributes.filterable_color && (
165
+ {item?.product?.attributes
166
+ ?.filterable_color && (
165
167
  <div>
166
168
  <span>
167
169
  {t('account.my_orders.detail.color')}
168
170
  </span>
169
- : {item.product.attributes.filterable_color}
171
+ :{' '}
172
+ {
173
+ item?.product?.attributes
174
+ ?.filterable_color
175
+ }
170
176
  </div>
171
177
  )}
172
178
 
173
- {item.product.attributes.size && (
179
+ {item?.product?.attributes?.size && (
174
180
  <div>
175
181
  <span>
176
182
  {t('account.my_orders.detail.size')}
177
183
  </span>
178
- :{item.product.attributes.size}
184
+ :{item?.product?.attributes?.size}
179
185
  </div>
180
186
  )}
181
187
 
@@ -183,7 +189,7 @@ export const AnonymousTrackingOrderDetail = ({ order }) => {
183
189
  <span>
184
190
  {t('account.my_orders.detail.code')}
185
191
  </span>
186
- : {item.product.base_code}
192
+ : {item?.product?.base_code}
187
193
  </div>
188
194
  </div>
189
195
  </div>
@@ -202,7 +208,7 @@ export const AnonymousTrackingOrderDetail = ({ order }) => {
202
208
 
203
209
  {(item.is_cancellable || item.is_refundable) &&
204
210
  order.is_cancellable &&
205
- item.status.value == '400' && (
211
+ item?.status?.value == '400' && (
206
212
  <div className="lg:ml-24">
207
213
  <Link
208
214
  href={`${ROUTES.ACCOUNT_ORDERS}/${order.id}/cancellation`}
@@ -256,29 +262,29 @@ export const AnonymousTrackingOrderDetail = ({ order }) => {
256
262
  <div className="flex justify-between text-sm text-black-700 mb-2">
257
263
  <p>
258
264
  <span>{t('account.my_orders.detail.subtotal')}</span> (
259
- {order?.orderitem_set.length}{' '}
265
+ {order?.orderitem_set?.length}{' '}
260
266
  <span>{t('account.my_orders.detail.items')}</span>)
261
267
  </p>
262
268
 
263
269
  <Price
264
270
  className="font-normal min-w-max"
265
271
  value={
266
- parseFloat(order.amount_without_discount) -
267
- parseFloat(order.shipping_amount)
272
+ parseFloat(order?.amount_without_discount || '0') -
273
+ parseFloat(order?.shipping_amount || '0')
268
274
  }
269
275
  />
270
276
  </div>
271
277
 
272
- {order.discountitem_set &&
273
- order.discountitem_set.map((item, index) => (
278
+ {order?.discountitem_set &&
279
+ order?.discountitem_set?.map((item, index) => (
274
280
  <div
275
281
  className="flex justify-between text-sm text-black-700 mb-2"
276
282
  key={index}
277
283
  >
278
- <p>{item.name}</p>
284
+ <p>{item?.name}</p>
279
285
  <Price
280
286
  className="font-normal min-w-max"
281
- value={item.amount}
287
+ value={item?.amount}
282
288
  useNegative
283
289
  />
284
290
  </div>
@@ -291,7 +297,8 @@ export const AnonymousTrackingOrderDetail = ({ order }) => {
291
297
  className="font-normal min-w-max"
292
298
  data-testid="account-orders-detail-total"
293
299
  value={
294
- parseFloat(order.amount) - parseFloat(order.shipping_amount)
300
+ parseFloat(order?.amount || '0') -
301
+ parseFloat(order?.shipping_amount || '0')
295
302
  }
296
303
  />
297
304
  </div>
@@ -65,6 +65,7 @@ export default function RedirectionPayment() {
65
65
 
66
66
  <Checkbox
67
67
  className="px-4 md:px-0"
68
+ data-testid="checkout-agreement"
68
69
  {...register('agreement')}
69
70
  error={errors.agreement}
70
71
  >
@@ -88,7 +89,10 @@ export default function RedirectionPayment() {
88
89
  </div>
89
90
  )}
90
91
 
91
- <Button className={twMerge('w-full md:w-36 px-4 md:px-0')}>
92
+ <Button
93
+ data-testid="checkout-submit-button"
94
+ className={twMerge('w-full md:w-36 px-4 md:px-0')}
95
+ >
92
96
  {payment_option.name}
93
97
  </Button>
94
98
  </form>
@@ -92,7 +92,11 @@ export default function ActionMenu() {
92
92
  ref={menu.miniBasket ? miniBasketRef : null}
93
93
  >
94
94
  {menu.action ? (
95
- <button onClick={menu.action} data-testid={menu.dataTestId}>
95
+ <button
96
+ onClick={menu.action}
97
+ data-testid={menu.dataTestId}
98
+ className="cursor-pointer"
99
+ >
96
100
  <Icon name={menu.icon} size={24} />
97
101
  {menu.badge}
98
102
  </button>
@@ -13,7 +13,8 @@ export interface PriceProps {
13
13
  export default function PriceWrapper(props: PriceProps) {
14
14
  const { t } = useLocalization();
15
15
  const { price, retailPrice } = props;
16
- const hasRetailPrice = parseFloat(retailPrice) > parseFloat(price);
16
+ const hasRetailPrice =
17
+ parseFloat(retailPrice || '0') > parseFloat(price || '0');
17
18
 
18
19
  return (
19
20
  <div className="flex items-center gap-3 justify-center h-full">
@@ -31,7 +32,11 @@ export default function PriceWrapper(props: PriceProps) {
31
32
  {hasRetailPrice && (
32
33
  <div className="flex flex-col items-center w-9 py-0.5 text-xs text-white bg-secondary">
33
34
  <span className="font-bold">
34
- {Math.round(100 - (parseInt(price) / parseInt(retailPrice)) * 100)}%
35
+ {Math.round(
36
+ 100 -
37
+ (parseInt(price || '0') / parseInt(retailPrice || '1')) * 100
38
+ )}
39
+ %
35
40
  </span>
36
41
  <span>{t('product.off')}</span>
37
42
  </div>
@@ -23,6 +23,7 @@ export default function ProductInfo({ data }: ProductPageProps) {
23
23
  const [isModalOpen, setIsModalOpen] = useState(false);
24
24
  const [stockAlertResponseMessage, setStockAlertResponseMessage] =
25
25
  useState(null);
26
+ const [isVariantLoading, setIsVariantLoading] = useState(false);
26
27
 
27
28
  const [addProduct, { isLoading: isAddToCartLoading }] =
28
29
  useAddProductToBasket();
@@ -30,6 +31,18 @@ export default function ProductInfo({ data }: ProductPageProps) {
30
31
  useAddStockAlertMutation();
31
32
  const inStock = data.selected_variant !== null || data.product.in_stock;
32
33
 
34
+ useEffect(() => {
35
+ isVariantSelectionComplete() && setIsVariantLoading(false);
36
+
37
+ !inStock && setIsVariantLoading(false);
38
+ }, [data]); // eslint-disable-line react-hooks/exhaustive-deps
39
+
40
+ useEffect(() => {
41
+ if (isVariantLoading) {
42
+ setProductError(null);
43
+ }
44
+ }, [isVariantLoading]);
45
+
33
46
  useEffect(() => {
34
47
  setCurrentUrl(window.location.href);
35
48
  }, [currentUrl]);
@@ -82,6 +95,12 @@ export default function ProductInfo({ data }: ProductPageProps) {
82
95
  return true;
83
96
  };
84
97
 
98
+ const isVariantSelectionComplete = () => {
99
+ return data?.variants.every((variant) =>
100
+ variant?.options.some((opt) => opt.is_selected)
101
+ );
102
+ };
103
+
85
104
  const addProductToStockAlertList = async () => {
86
105
  try {
87
106
  await addStockAlert({
@@ -174,7 +193,10 @@ export default function ProductInfo({ data }: ProductPageProps) {
174
193
  key={variant.attribute_key}
175
194
  {...variant}
176
195
  className="items-center mt-8"
177
- onChange={() => setProductError(null)}
196
+ onChange={() => {
197
+ setProductError(null);
198
+ setIsVariantLoading(true);
199
+ }}
178
200
  />
179
201
  ))}
180
202
  </div>
@@ -186,7 +208,9 @@ export default function ProductInfo({ data }: ProductPageProps) {
186
208
  )}
187
209
 
188
210
  <Button
189
- disabled={isAddToCartLoading || isAddToStockAlertLoading}
211
+ disabled={
212
+ isAddToCartLoading || isAddToStockAlertLoading || isVariantLoading
213
+ }
190
214
  className={clsx(
191
215
  'fixed bottom-0 right-0 w-1/2 h-14 z-20 flex items-center justify-center fill-primary-foreground',
192
216
  'hover:fill-primary sm:relative sm:w-full sm:mt-3 sm:font-semibold sm:h-12'
@@ -202,7 +226,13 @@ export default function ProductInfo({ data }: ProductPageProps) {
202
226
  }}
203
227
  data-testid="product-add-to-cart"
204
228
  >
205
- {inStock ? (
229
+ {isVariantLoading ? (
230
+ <Icon
231
+ name="spinner"
232
+ size={20}
233
+ className="animate-spin mr-4 fill-primary"
234
+ />
235
+ ) : inStock ? (
206
236
  <span>{t('product.add_to_cart')}</span>
207
237
  ) : (
208
238
  <>
@@ -1,3 +1,4 @@
1
+ const getAkinonNextContent = require('@akinon/next/tailwind/content');
1
2
  const deepMerge = require('@akinon/next/utils/deep-merge');
2
3
  const plugins = require('./src/plugins');
3
4
  const fs = require('fs');
@@ -18,13 +19,16 @@ if (themeName !== 'default' && fs.existsSync(themeConfigPath)) {
18
19
 
19
20
  const defaultConfig = {
20
21
  content: [
21
- ...plugins
22
- .map((plugin) => [
23
- `./node_modules/@akinon/${plugin}/**/*.{js,ts,jsx,tsx}`,
24
- `../../node_modules/@akinon/${plugin}/**/*.{js,ts,jsx,tsx}`
25
- ])
26
- .flat()
27
- ]
22
+ './src/app/**/*.{js,ts,jsx,tsx}',
23
+ './src/pages/**/*.{js,ts,jsx,tsx}',
24
+ './src/components/**/*.{js,ts,jsx,tsx}',
25
+ './src/views/**/*.{js,ts,jsx,tsx}',
26
+ './src/widgets/**/*.{js,ts,jsx,tsx}',
27
+ './src/hooks/**/*.{js,ts,jsx,tsx}',
28
+ './src/utils/**/*.{js,ts,jsx,tsx}',
29
+ ...getAkinonNextContent(plugins)
30
+ ],
31
+ plugins: [require('@tailwindcss/typography')]
28
32
  };
29
33
 
30
34
  if (Object.keys(themeOverrides).length === 0) {
@@ -0,0 +1,30 @@
1
+ const path = require('path');
2
+ const jscodeshift = require('jscodeshift/src/Runner');
3
+
4
+ const codemodScript = path.resolve(__dirname, 'transform.js');
5
+
6
+ const transform = () => {
7
+ const workingDir = path.resolve(process.cwd());
8
+
9
+ jscodeshift
10
+ .run(codemodScript, [workingDir], {
11
+ verbose: 0,
12
+ dry: false,
13
+ print: false,
14
+ extensions: 'js',
15
+ ignorePattern: '**/node_modules/**',
16
+ filter: '**/tailwind.config.js'
17
+ })
18
+ .then(
19
+ (stats) => {
20
+ console.log(`Codemod completed. Stats:`, stats);
21
+ },
22
+ (error) => {
23
+ console.error(`Error executing codemod: ${error.message}`);
24
+ }
25
+ );
26
+ };
27
+
28
+ module.exports = {
29
+ transform
30
+ };
@@ -0,0 +1,102 @@
1
+ function transform(fileInfo, api) {
2
+ const j = api.jscodeshift;
3
+ const root = j(fileInfo.source);
4
+
5
+ if (!fileInfo.path.includes('tailwind.config.js')) {
6
+ return fileInfo.source;
7
+ }
8
+
9
+ console.log(`Processing file: ${fileInfo.path}`);
10
+
11
+ const hasAkinonNextImport = root.find(j.VariableDeclarator, {
12
+ id: { name: 'getAkinonNextContent' }
13
+ });
14
+
15
+ if (hasAkinonNextImport.size() === 0) {
16
+ const requireStatement = j.variableDeclaration('const', [
17
+ j.variableDeclarator(
18
+ j.identifier('getAkinonNextContent'),
19
+ j.callExpression(j.identifier('require'), [
20
+ j.literal('@akinon/next/tailwind/content')
21
+ ])
22
+ )
23
+ ]);
24
+
25
+ root.get().node.program.body.unshift(requireStatement);
26
+
27
+ console.log(`Added getAkinonNextContent import to ${fileInfo.path}`);
28
+ }
29
+
30
+ const defaultConfig = root
31
+ .find(j.VariableDeclarator, {
32
+ id: { name: 'defaultConfig' },
33
+ init: { type: 'ObjectExpression' }
34
+ })
35
+ .paths()[0];
36
+
37
+ if (!defaultConfig) {
38
+ console.log(`No defaultConfig found in ${fileInfo.path}`);
39
+ return fileInfo.source;
40
+ }
41
+
42
+ const contentArray = defaultConfig.value.init.properties.find(
43
+ (prop) =>
44
+ prop.key.name === 'content' && prop.value.type === 'ArrayExpression'
45
+ );
46
+
47
+ if (!contentArray) {
48
+ console.log(`No content array found in defaultConfig`);
49
+ return fileInfo.source;
50
+ }
51
+
52
+ const pluginsVarName = root
53
+ .find(j.VariableDeclarator, {
54
+ id: { name: 'plugins' },
55
+ init: {
56
+ type: 'CallExpression',
57
+ callee: { name: 'require' }
58
+ }
59
+ })
60
+ .paths()[0]?.value.id.name;
61
+
62
+ if (!pluginsVarName) {
63
+ console.log(`No plugins variable found in ${fileInfo.path}`);
64
+ return fileInfo.source;
65
+ }
66
+
67
+ const contentElements = contentArray.value.elements;
68
+
69
+ const filteredElements = contentElements.filter((element) => {
70
+ if (element.type === 'SpreadElement') {
71
+ if (
72
+ element.argument.type === 'CallExpression' &&
73
+ element.argument.callee.object?.callee.object.name === 'plugins'
74
+ ) {
75
+ return false;
76
+ }
77
+
78
+ if (
79
+ element.argument.type === 'CallExpression' &&
80
+ element.argument.callee.name === 'getAkinonNextContent'
81
+ ) {
82
+ return false;
83
+ }
84
+ }
85
+ return true;
86
+ });
87
+
88
+ filteredElements.push(
89
+ j.spreadElement(
90
+ j.callExpression(j.identifier('getAkinonNextContent'), [
91
+ j.identifier(pluginsVarName)
92
+ ])
93
+ )
94
+ );
95
+
96
+ contentArray.value.elements = filteredElements;
97
+
98
+ console.log(`Successfully updated ${fileInfo.path}`);
99
+ return root.toSource();
100
+ }
101
+
102
+ module.exports = transform;
@@ -5,7 +5,6 @@ const { hideBin } = require('yargs/helpers');
5
5
  const args = yargs(hideBin(process.argv)).argv;
6
6
 
7
7
  export default () => {
8
- const workingDir = path.resolve(process.cwd());
9
8
  const codemodName = args.codemod;
10
9
  const codemodPath = path.resolve(
11
10
  __dirname,
@@ -2,8 +2,7 @@ import * as fs from 'fs';
2
2
  import path from 'path';
3
3
  import { execSync } from 'child_process';
4
4
  import semver from 'semver';
5
-
6
- const Prompt = require('prompt-checkbox');
5
+ import { checkbox } from '@inquirer/prompts';
7
6
 
8
7
  const rootDir = path.resolve(process.cwd());
9
8
 
@@ -120,36 +119,25 @@ export default async () => {
120
119
  }
121
120
  ];
122
121
 
123
- const prompt = new Prompt({
124
- name: 'plugins',
125
- message: 'Please check/uncheck plugins to install/uninstall.',
126
- type: 'checkbox',
127
- default: installedPlugins.map((p) =>
128
- definedPlugins.findIndex((dp) => dp.value === p)
129
- ),
130
- choices: definedPlugins.map((p, index) => `${index + 1}) ${p.name}`)
131
- });
132
-
133
- prompt.ask(async (answers: Array<string>) => {
134
- const formattedAnswers = answers.map((answer) =>
135
- answer.replace(/\d\)\s/, '')
136
- );
137
-
138
- const values = formattedAnswers.map(
139
- (answer) => definedPlugins.find((p) => p.name === answer)?.value
140
- );
141
-
142
- if (formattedAnswers.length) {
143
- console.log(`\nInstalling ${formattedAnswers.join(', ')}.`);
144
- } else {
145
- console.log(`\nUninstalling all plugins.`);
122
+ try {
123
+ const answers = await checkbox({
124
+ message: 'Please check/uncheck plugins to install/uninstall.',
125
+ choices: definedPlugins.map((plugin) => ({
126
+ name: plugin.name,
127
+ value: plugin.value,
128
+ checked: installedPlugins.includes(plugin.value)
129
+ }))
130
+ });
131
+
132
+ if (!answers.length) {
133
+ console.log('\x1b[33m%s\x1b[0m', `\nUninstalling all plugins.`);
146
134
  }
147
135
 
148
- console.log(`\nPlease wait...`);
136
+ console.log('\x1b[36m%s\x1b[0m', `\nPlease wait...`);
149
137
 
150
138
  fs.writeFileSync(
151
139
  pluginsFilePath,
152
- `module.exports = ${JSON.stringify(values)};\n`,
140
+ `module.exports = ${JSON.stringify(answers)};\n`,
153
141
  {
154
142
  encoding: 'utf-8'
155
143
  }
@@ -159,11 +147,13 @@ export default async () => {
159
147
 
160
148
  console.log(
161
149
  '\x1b[32m%s\x1b[0m',
162
- `\n ✓ ${
163
- formattedAnswers.length
150
+ `\n✓ ${
151
+ answers.length
164
152
  ? 'Installed selected plugins'
165
153
  : 'Uninstalled all plugins'
166
154
  }.\n`
167
155
  );
168
- });
156
+ } catch (error) {
157
+ process.exit(1);
158
+ }
169
159
  };
@@ -8,7 +8,6 @@ const yargs = require('yargs/yargs');
8
8
  const { hideBin } = require('yargs/helpers');
9
9
  const args = yargs(hideBin(process.argv)).argv;
10
10
  exports.default = () => {
11
- const workingDir = path_1.default.resolve(process.cwd());
12
11
  const codemodName = args.codemod;
13
12
  const codemodPath = path_1.default.resolve(__dirname, `../../codemods/${codemodName}/index.js`);
14
13
  const codemod = require(codemodPath);
@@ -49,7 +49,7 @@ const fs = __importStar(require("fs"));
49
49
  const path_1 = __importDefault(require("path"));
50
50
  const child_process_1 = require("child_process");
51
51
  const semver_1 = __importDefault(require("semver"));
52
- const Prompt = require('prompt-checkbox');
52
+ const prompts_1 = require("@inquirer/prompts");
53
53
  const rootDir = path_1.default.resolve(process.cwd());
54
54
  function checkVersion(pkg) {
55
55
  return __awaiter(this, void 0, void 0, function* () {
@@ -143,29 +143,28 @@ exports.default = () => __awaiter(void 0, void 0, void 0, function* () {
143
143
  value: 'pz-tamara-extension'
144
144
  }
145
145
  ];
146
- const prompt = new Prompt({
147
- name: 'plugins',
148
- message: 'Please check/uncheck plugins to install/uninstall.',
149
- type: 'checkbox',
150
- default: installedPlugins.map((p) => definedPlugins.findIndex((dp) => dp.value === p)),
151
- choices: definedPlugins.map((p, index) => `${index + 1}) ${p.name}`)
152
- });
153
- prompt.ask((answers) => __awaiter(void 0, void 0, void 0, function* () {
154
- const formattedAnswers = answers.map((answer) => answer.replace(/\d\)\s/, ''));
155
- const values = formattedAnswers.map((answer) => { var _a; return (_a = definedPlugins.find((p) => p.name === answer)) === null || _a === void 0 ? void 0 : _a.value; });
156
- if (formattedAnswers.length) {
157
- console.log(`\nInstalling ${formattedAnswers.join(', ')}.`);
158
- }
159
- else {
160
- console.log(`\nUninstalling all plugins.`);
146
+ try {
147
+ const answers = yield (0, prompts_1.checkbox)({
148
+ message: 'Please check/uncheck plugins to install/uninstall.',
149
+ choices: definedPlugins.map((plugin) => ({
150
+ name: plugin.name,
151
+ value: plugin.value,
152
+ checked: installedPlugins.includes(plugin.value)
153
+ }))
154
+ });
155
+ if (!answers.length) {
156
+ console.log('\x1b[33m%s\x1b[0m', `\nUninstalling all plugins.`);
161
157
  }
162
- console.log(`\nPlease wait...`);
163
- fs.writeFileSync(pluginsFilePath, `module.exports = ${JSON.stringify(values)};\n`, {
158
+ console.log('\x1b[36m%s\x1b[0m', `\nPlease wait...`);
159
+ fs.writeFileSync(pluginsFilePath, `module.exports = ${JSON.stringify(answers)};\n`, {
164
160
  encoding: 'utf-8'
165
161
  });
166
162
  (0, child_process_1.execSync)('yarn install', { stdio: 'pipe' });
167
- console.log('\x1b[32m%s\x1b[0m', `\n ✓ ${formattedAnswers.length
163
+ console.log('\x1b[32m%s\x1b[0m', `\n✓ ${answers.length
168
164
  ? 'Installed selected plugins'
169
165
  : 'Uninstalled all plugins'}.\n`);
170
- }));
166
+ }
167
+ catch (error) {
168
+ process.exit(1);
169
+ }
171
170
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akinon/projectzero",
3
- "version": "2.0.0-beta.10",
3
+ "version": "2.0.0-beta.12",
4
4
  "private": false,
5
5
  "description": "CLI tool to manage your Project Zero Next project",
6
6
  "bin": {
@@ -19,8 +19,9 @@
19
19
  "@types/temp": "0.9.4"
20
20
  },
21
21
  "dependencies": {
22
+ "jscodeshift": "^0.15.1",
23
+ "@inquirer/prompts": "7.5.0",
22
24
  "loading-spinner": "1.2.1",
23
- "prompt-checkbox": "2.2.0",
24
25
  "semver": "7.6.2",
25
26
  "temp": "0.9.4",
26
27
  "yargs": "^17.6.0"