@ikas/storefront-next 4.0.0-alpha.10

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.
@@ -0,0 +1,618 @@
1
+ import fs from "fs";
2
+ import getConfig from "next/config.js";
3
+ import { GetServerSidePropsContext, GetStaticPropsContext } from "next";
4
+ import { ParsedUrlQuery } from "querystring";
5
+ import {
6
+ IkasCustomerReviewSettings,
7
+ IkasMerchantSettings,
8
+ IkasProductBackInStockSettings,
9
+ IkasSalesChannel,
10
+ IkasStorefront,
11
+ IkasStorefrontRouting,
12
+ IkasStorefrontThemeLocalization,
13
+ IkasThemeJson,
14
+ IkasThemeJsonFavicon,
15
+ IkasThemeJsonPageType,
16
+ IkasThemeJsonSettings,
17
+ IkasThemeJsonStockPreference,
18
+ } from "@ikas/storefront-models";
19
+ import { IkasPageDataProvider } from "@ikas/storefront-providers";
20
+ import { IkasStorefrontConfig } from "@ikas/storefront-config";
21
+ import {
22
+ listCheckoutSettings,
23
+ listMerchantSettings,
24
+ IkasAPIClientConfig,
25
+ getStorefrontSettings,
26
+ IkasStorefrontSettings,
27
+ } from "@ikas/storefront-api";
28
+ import { getGoogleFontHref } from "../utils/google-fonts";
29
+ import { I18NFileReader } from "../utils/i18n";
30
+ import { createFile, deleteDirContent } from "../utils/fs";
31
+
32
+ export class IkasNextPageDataProvider {
33
+ static startTime = Date.now();
34
+
35
+ static readLocalTheme(): Promise<IkasThemeJson> {
36
+ return new Promise((resolve, reject) => {
37
+ const themeJSONPath = "./src/theme.json";
38
+
39
+ fs.readFile(
40
+ themeJSONPath,
41
+ {
42
+ flag: "a+",
43
+ },
44
+ function (err, file) {
45
+ if (err) {
46
+ return reject(err);
47
+ }
48
+ const result = file.length ? JSON.parse(file.toString()) : {};
49
+ resolve(result);
50
+ }
51
+ );
52
+ });
53
+ }
54
+
55
+ static readSettingsFile(): Promise<SettingsData | null> {
56
+ return new Promise((resolve) => {
57
+ const { serverRuntimeConfig } = getConfig();
58
+ const settingsPath = serverRuntimeConfig.SETTINGS;
59
+
60
+ fs.readFile(
61
+ settingsPath,
62
+ {
63
+ flag: "a+",
64
+ },
65
+ function (err, file) {
66
+ if (err) {
67
+ console.error("SETTINGS FILE READ ERROR!!!");
68
+ console.error(err);
69
+ return resolve(null);
70
+ }
71
+ const result = file.length ? JSON.parse(file.toString()) : {};
72
+ resolve(result);
73
+ }
74
+ );
75
+ });
76
+ }
77
+
78
+ static async cacheLocalSettingsFile(settings: IkasStorefrontSettings) {
79
+ const cacheFileFolderPath = ".ikas";
80
+ await deleteDirContent(cacheFileFolderPath);
81
+
82
+ const cacheFileName = `settings-${this.startTime}.json`;
83
+ await createFile(
84
+ cacheFileFolderPath,
85
+ cacheFileName,
86
+ JSON.stringify(settings, null, 2)
87
+ );
88
+ }
89
+
90
+ static readLocalSettingsFile() {
91
+ try {
92
+ const fileContent = fs.readFileSync(
93
+ `.ikas/settings-${this.startTime}.json`
94
+ );
95
+
96
+ if (fileContent && fileContent.length)
97
+ return JSON.parse(fileContent.toString());
98
+ } catch {}
99
+ }
100
+
101
+ static setAPIClientConfig() {
102
+ IkasAPIClientConfig.URL = IkasStorefrontConfig.getApiUrl() || "";
103
+ IkasAPIClientConfig.HEADERS = {
104
+ "x-api-key": IkasStorefrontConfig.getApiKey() || "",
105
+ "x-sfid": IkasStorefrontConfig.getStorefrontId() || "",
106
+ "x-sfrid": IkasStorefrontConfig.getStorefrontRoutingId() || "",
107
+ };
108
+
109
+ if (IkasStorefrontConfig.getCustomerToken()) {
110
+ IkasAPIClientConfig.TOKEN = IkasStorefrontConfig.getCustomerToken() || "";
111
+ }
112
+ }
113
+
114
+ static async getLocalSettings(locale: string): Promise<SettingsData | null> {
115
+ let settings: IkasStorefrontSettings =
116
+ await IkasNextPageDataProvider.readLocalSettingsFile();
117
+
118
+ if (!settings) {
119
+ const settingsResponse = await getStorefrontSettings();
120
+
121
+ if (!settingsResponse.isSuccess || !settingsResponse.data) {
122
+ console.error("Storefront settings fetch failed!");
123
+ console.error(settingsResponse);
124
+ return null;
125
+ }
126
+
127
+ settings = settingsResponse.data;
128
+ await this.cacheLocalSettingsFile(settings);
129
+ }
130
+
131
+ const storefront = settings.storefront;
132
+ const salesChannel = settings.salesChannel;
133
+ const storefrontJSScripts = []; // Not using the settings one on purpose, no need to run scripts on localhost
134
+ const productBackInStockSettings: IkasProductBackInStockSettings | null =
135
+ settings.productBackInStockSettings
136
+ ? {
137
+ customerLoginRequired:
138
+ settings.productBackInStockSettings.customerLoginRequired,
139
+ }
140
+ : null;
141
+ const customerReviewSettings: IkasCustomerReviewSettings | null =
142
+ settings.customerReviewSettings
143
+ ? {
144
+ customerLoginRequired:
145
+ settings.customerReviewSettings.customerLoginRequired || false,
146
+ customerPurchaseRequired:
147
+ settings.customerReviewSettings.customerPurchaseRequired || false,
148
+ }
149
+ : null;
150
+
151
+ const localTheme = await IkasNextPageDataProvider.readLocalTheme();
152
+ const colorScript = IkasNextPageDataProvider.createColorScript(
153
+ localTheme.settings
154
+ );
155
+ const fontScript = IkasNextPageDataProvider.createFontScript(
156
+ localTheme.settings
157
+ );
158
+
159
+ if (colorScript) storefrontJSScripts.push(colorScript);
160
+ if (fontScript) storefrontJSScripts.push(fontScript);
161
+
162
+ return {
163
+ storefront: storefront,
164
+ themeLocalization: {
165
+ id: "",
166
+ locale: "en",
167
+ privacyPolicy: null,
168
+ returnPolicy: null,
169
+ storefrontId: storefront.id,
170
+ storefrontThemeId: "",
171
+ termsOfService: null,
172
+ themeJson: localTheme,
173
+ },
174
+ salesChannel,
175
+ routing: storefront.routings.length
176
+ ? storefront.routings.find(
177
+ (r) => r.locale === locale || r.id === locale
178
+ ) || storefront.routings[0]
179
+ : {
180
+ countryCodes: [],
181
+ domain: "",
182
+ dynamicCurrencySettings: {
183
+ roundingFormat: null,
184
+ targetCurrencyCode: "",
185
+ },
186
+ id: "",
187
+ locale: "en",
188
+ path: null,
189
+ priceListId: null,
190
+ },
191
+ favicon: localTheme.settings.favicon,
192
+ stockPreference: localTheme.settings.stockPreference,
193
+ storefrontJSScripts,
194
+ domain: "localhost:3333",
195
+ productBackInStockSettings,
196
+ customerReviewSettings,
197
+ merchantSettings: settings.merchantSettings,
198
+ };
199
+ }
200
+
201
+ static async getProdSettings(locale: string): Promise<SettingsData | null> {
202
+ return new Promise(async (resolve) => {
203
+ const settings = await IkasNextPageDataProvider.readSettingsFile();
204
+ if (!settings || !settings.localizationMap) return resolve(null);
205
+
206
+ const storefront = settings.storefront;
207
+ const salesChannel = settings.salesChannel;
208
+ const localizationMap = settings.localizationMap;
209
+ const storefrontJSScripts = settings.storefrontJSScripts || [];
210
+ const domain = settings.domain;
211
+ const productBackInStockSettings: IkasProductBackInStockSettings | null =
212
+ settings.productBackInStockSettings
213
+ ? {
214
+ customerLoginRequired:
215
+ settings.productBackInStockSettings.customerLoginRequired,
216
+ }
217
+ : null;
218
+ const customerReviewSettings: IkasCustomerReviewSettings | null =
219
+ settings.customerReviewSettings
220
+ ? {
221
+ customerLoginRequired:
222
+ settings.customerReviewSettings.customerLoginRequired || false,
223
+ customerPurchaseRequired:
224
+ settings.customerReviewSettings.customerPurchaseRequired ||
225
+ false,
226
+ }
227
+ : null;
228
+
229
+ let merchantSettings = settings.merchantSettings;
230
+ if (!merchantSettings) {
231
+ const response = await listMerchantSettings({});
232
+ if (response.isSuccess && response.data) {
233
+ merchantSettings = response.data;
234
+ } else {
235
+ console.error("MERCHANT SETTINGS FETCH FAILED!");
236
+ return resolve(null);
237
+ }
238
+ }
239
+
240
+ const themeLocalizationPath = localizationMap[locale];
241
+ const routing = storefront.routings.find(
242
+ (r) => r.id === locale || r.path === locale
243
+ );
244
+
245
+ if (!themeLocalizationPath || !routing) {
246
+ console.error("THEME LOCALIZATION PATH OR ROUTING MISSING!!!");
247
+ return resolve(null);
248
+ }
249
+
250
+ fs.readFile(
251
+ themeLocalizationPath,
252
+ {
253
+ flag: "a+",
254
+ },
255
+ function (err, file) {
256
+ if (err) {
257
+ console.error("THEME LOCALIZATION FILE READ ERROR!!!");
258
+ console.error(err);
259
+ return resolve(null);
260
+ }
261
+ const result = file.length ? JSON.parse(file.toString()) : {};
262
+ const themeLocalization = result as IkasStorefrontThemeLocalization;
263
+ const favicon = themeLocalization.themeJson.settings.favicon;
264
+ const stockPreference =
265
+ themeLocalization.themeJson.settings.stockPreference;
266
+
267
+ if (themeLocalization.themeJson.settings) {
268
+ const colorScript = IkasNextPageDataProvider.createColorScript(
269
+ themeLocalization.themeJson.settings
270
+ );
271
+ const fontScript = IkasNextPageDataProvider.createFontScript(
272
+ themeLocalization.themeJson.settings
273
+ );
274
+
275
+ if (colorScript) storefrontJSScripts.push(colorScript);
276
+ if (fontScript) storefrontJSScripts.push(fontScript);
277
+ }
278
+
279
+ resolve({
280
+ storefront,
281
+ themeLocalization,
282
+ salesChannel,
283
+ routing,
284
+ favicon,
285
+ stockPreference,
286
+ storefrontJSScripts,
287
+ domain,
288
+ productBackInStockSettings,
289
+ customerReviewSettings,
290
+ merchantSettings,
291
+ });
292
+ }
293
+ );
294
+ });
295
+ }
296
+
297
+ static async getSettings(locale: string): Promise<SettingsData | null> {
298
+ const isLocal = process.env.NEXT_PUBLIC_ENV === "local";
299
+
300
+ if (isLocal) {
301
+ return await this.getLocalSettings(locale);
302
+ } else {
303
+ return await this.getProdSettings(locale);
304
+ }
305
+ }
306
+
307
+ static async setStorefrontConfig(settings: SettingsData) {
308
+ const {
309
+ storefront,
310
+ salesChannel,
311
+ routing,
312
+ favicon,
313
+ stockPreference,
314
+ storefrontJSScripts,
315
+ domain,
316
+ productBackInStockSettings,
317
+ customerReviewSettings,
318
+ merchantSettings,
319
+ } = settings;
320
+
321
+ IkasStorefrontConfig.init({
322
+ apiUrl: process.env.NEXT_PUBLIC_GQL_URL,
323
+ adminApiUrl: process.env.NEXT_PUBLIC_UPLOAD_GQL_URL,
324
+ cdnUrl: process.env.NEXT_PUBLIC_IMG_BASE_URL,
325
+ storefrontId: storefront.id,
326
+ storefrontRoutingId: routing.id,
327
+ storefrontThemeId: storefront.mainStorefrontThemeId!,
328
+ salesChannelId: storefront.salesChannelId!,
329
+ priceListId: routing.priceListId || undefined,
330
+ stockLocationIds: salesChannel.stockLocations?.map((sl) => sl.id),
331
+ routings: storefront.routings,
332
+ paymentGateways: salesChannel.paymentGateways || [],
333
+ gtmId: storefront.gtmId || undefined,
334
+ fbpId: storefront.fbpId || undefined,
335
+ analytics4Id: storefront.analytics4Id || undefined,
336
+ universalAnalyticsId: storefront.universalAnalyticsId || undefined,
337
+ tiktokPixelId: storefront.tiktokPixelId || undefined,
338
+ favicon: favicon || null,
339
+ pickUpStockLocationIds: storefront.pickUpStockLocationIds
340
+ ? storefront.pickUpStockLocationIds.length
341
+ ? storefront.pickUpStockLocationIds
342
+ : null
343
+ : null,
344
+ stockPreference: stockPreference || null,
345
+ storefrontJSScripts: storefrontJSScripts || [],
346
+ domain: domain,
347
+ productBackInStockSettings: productBackInStockSettings,
348
+ customerReviewSettings: customerReviewSettings,
349
+ merchantSettings,
350
+ });
351
+ }
352
+
353
+ static async setTranslations(
354
+ settings: SettingsData,
355
+ componentIds: string[],
356
+ pageType?: IkasThemeJsonPageType,
357
+ isEditor?: boolean
358
+ ) {
359
+ const { serverRuntimeConfig } = getConfig();
360
+ const routing = settings.routing;
361
+ const isLocal = process.env.NEXT_PUBLIC_ENV === "local";
362
+
363
+ const components = settings.themeLocalization.themeJson.components.filter(
364
+ (c) => isEditor || componentIds.includes(c.id)
365
+ );
366
+ const namespaces = ["common", ...components.map((c) => c.dir)];
367
+
368
+ if (pageType === IkasThemeJsonPageType.CHECKOUT || isEditor) {
369
+ namespaces.push("checkout-page");
370
+ }
371
+
372
+ const nextI18nConf = serverRuntimeConfig.nextI18nConf;
373
+ const currentLocale = routing.locale;
374
+
375
+ const i18nReader = new I18NFileReader(
376
+ currentLocale,
377
+ namespaces,
378
+ isLocal ? undefined : nextI18nConf.localePath
379
+ );
380
+
381
+ const translations = await i18nReader.read();
382
+ IkasStorefrontConfig.init({
383
+ translations,
384
+ });
385
+ }
386
+
387
+ static async getExtraProps(
388
+ settings: SettingsData,
389
+ provider: IkasPageDataProvider,
390
+ pageType?: IkasThemeJsonPageType
391
+ ) {
392
+ const extraProps: Record<string, any> = {};
393
+ const themeLocalization = settings.themeLocalization;
394
+
395
+ if (pageType === IkasThemeJsonPageType.CHECKOUT) {
396
+ const checkoutComponent = provider.page?.components[0];
397
+
398
+ if (checkoutComponent) {
399
+ const checkoutSettings = await listCheckoutSettings({});
400
+ const customizationProps: IkasCheckoutCustomizationProps = {
401
+ showTax: checkoutComponent.propValues["showTax"] ?? true,
402
+ buttonBgColor: checkoutComponent.propValues["buttonBgColor"],
403
+ buttonTextColor: checkoutComponent.propValues["buttonTextColor"],
404
+ buttonDisabledBgColor:
405
+ checkoutComponent.propValues["buttonDisabledBgColor"],
406
+ buttonDisabledTextColor:
407
+ checkoutComponent.propValues["buttonDisabledTextColor"],
408
+
409
+ primaryTextColor: checkoutComponent.propValues["primaryTextColor"],
410
+ secondaryTextColor:
411
+ checkoutComponent.propValues["secondaryTextColor"],
412
+
413
+ primaryBgColor: checkoutComponent.propValues["primaryBgColor"],
414
+ secondaryBgColor: checkoutComponent.propValues["secondaryBgColor"],
415
+ borderColor: checkoutComponent.propValues["borderColor"],
416
+ cardBgColor: checkoutComponent.propValues["cardBgColor"],
417
+
418
+ errorColor: checkoutComponent.propValues["errorColor"],
419
+ errorLightColor: checkoutComponent.propValues["errorLightColor"],
420
+ warningColor: checkoutComponent.propValues["warningColor"],
421
+ warningLightColor: checkoutComponent.propValues["warningLightColor"],
422
+ successColor: checkoutComponent.propValues["successColor"],
423
+ successLightColor: checkoutComponent.propValues["successLightColor"],
424
+ };
425
+
426
+ extraProps.customizationProps = customizationProps;
427
+ extraProps.returnPolicy = themeLocalization.returnPolicy;
428
+ extraProps.privacyPolicy = themeLocalization.privacyPolicy;
429
+ extraProps.termsOfService = themeLocalization.termsOfService;
430
+ extraProps.checkoutSettings = checkoutSettings?.data?.length
431
+ ? checkoutSettings.data[0]
432
+ : null;
433
+ }
434
+ }
435
+
436
+ return extraProps;
437
+ }
438
+
439
+ static async getPageData(
440
+ context:
441
+ | GetStaticPropsContext<ParsedUrlQuery>
442
+ | GetServerSidePropsContext<ParsedUrlQuery>,
443
+ isServer: boolean,
444
+ pageType?: IkasThemeJsonPageType,
445
+ possiblePageTypes?: IkasThemeJsonPageType[],
446
+ isEditor?: boolean
447
+ ) {
448
+ const isLocal = process.env.NEXT_PUBLIC_ENV === "local";
449
+ const isProdEditor = !isLocal && isEditor;
450
+
451
+ IkasNextPageDataProvider.setAPIClientConfig();
452
+
453
+ IkasStorefrontConfig.init({
454
+ apiUrl: process.env.NEXT_PUBLIC_GQL_URL,
455
+ adminApiUrl: process.env.NEXT_PUBLIC_UPLOAD_GQL_URL,
456
+ cdnUrl: process.env.NEXT_PUBLIC_IMG_BASE_URL,
457
+ });
458
+
459
+ // Local editor - prod deploy - local build
460
+ if (!isProdEditor) {
461
+ const locale = context.locale;
462
+
463
+ if (!locale) {
464
+ return {
465
+ props: {},
466
+ notFound: true,
467
+ };
468
+ }
469
+
470
+ const settings = await IkasNextPageDataProvider.getSettings(locale);
471
+
472
+ if (
473
+ !settings ||
474
+ !settings.storefront.mainStorefrontThemeId ||
475
+ !settings.storefront.salesChannelId
476
+ ) {
477
+ return {
478
+ props: {},
479
+ notFound: true,
480
+ };
481
+ }
482
+
483
+ await this.setStorefrontConfig(settings);
484
+
485
+ const themeLocalization = settings.themeLocalization;
486
+ const provider = new IkasPageDataProvider(
487
+ themeLocalization.themeJson,
488
+ context.params,
489
+ pageType
490
+ );
491
+ provider.possiblePageTypes =
492
+ possiblePageTypes || (pageType ? [pageType] : []);
493
+
494
+ if (!isEditor) {
495
+ await provider.getPageData();
496
+ if (!provider.page) {
497
+ return {
498
+ props: {},
499
+ notFound: true,
500
+ };
501
+ }
502
+ }
503
+
504
+ const componentIds = isEditor
505
+ ? provider.theme.components.map((c) => c.id)
506
+ : provider.page?.components.map((pc) => pc.componentId) || [];
507
+ await this.setTranslations(settings, componentIds, pageType, isEditor);
508
+
509
+ const extraProps = await this.getExtraProps(settings, provider, pageType);
510
+
511
+ if (isServer)
512
+ return {
513
+ props: {
514
+ ...provider.nextPageData.props,
515
+ ...extraProps,
516
+ },
517
+ };
518
+ else {
519
+ return {
520
+ props: {
521
+ ...provider.nextPageData.props,
522
+ ...extraProps,
523
+ },
524
+ revalidate: 60,
525
+ };
526
+ }
527
+ } else {
528
+ return {
529
+ props: {},
530
+ };
531
+ }
532
+ }
533
+
534
+ static async getStaticProps(
535
+ context: GetStaticPropsContext<ParsedUrlQuery>,
536
+ pageType?: IkasThemeJsonPageType,
537
+ possiblePageTypes?: IkasThemeJsonPageType[],
538
+ isEditor?: boolean
539
+ ) {
540
+ return await IkasNextPageDataProvider.getPageData(
541
+ context,
542
+ false,
543
+ pageType,
544
+ possiblePageTypes,
545
+ isEditor
546
+ );
547
+ }
548
+
549
+ static async getServerSideProps(
550
+ context: GetServerSidePropsContext<ParsedUrlQuery>,
551
+ pageType?: IkasThemeJsonPageType
552
+ ) {
553
+ return await IkasNextPageDataProvider.getPageData(context, true, pageType);
554
+ }
555
+
556
+ static createColorScript(settings: IkasThemeJsonSettings) {
557
+ if (!settings.colors) return;
558
+
559
+ return `<script>${settings.colors
560
+ .map(
561
+ (sc) =>
562
+ `document.documentElement.style.setProperty("${sc.key}","${sc.color}");`
563
+ )
564
+ .join("\r\n")}</script>
565
+ `;
566
+ }
567
+
568
+ static createFontScript(settings: IkasThemeJsonSettings) {
569
+ const fontHref = getGoogleFontHref(settings.fontFamily);
570
+
571
+ if (fontHref) {
572
+ return `<link id="ikas-font" rel="stylesheet" href="${fontHref}">
573
+ <style>
574
+ body {
575
+ font-family: '${settings.fontFamily.name}', -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !important;
576
+ }
577
+ </style>`;
578
+ }
579
+ }
580
+ }
581
+
582
+ export type SettingsData = {
583
+ storefront: IkasStorefront;
584
+ themeLocalization: IkasStorefrontThemeLocalization;
585
+ salesChannel: IkasSalesChannel;
586
+ routing: IkasStorefrontRouting;
587
+ localizationMap?: Record<string, any>;
588
+ favicon: IkasThemeJsonFavicon;
589
+ stockPreference: IkasThemeJsonStockPreference;
590
+ storefrontJSScripts: string[];
591
+ domain: string;
592
+ productBackInStockSettings: IkasProductBackInStockSettings | null;
593
+ customerReviewSettings: IkasCustomerReviewSettings | null;
594
+ merchantSettings: IkasMerchantSettings;
595
+ };
596
+
597
+ export type IkasCheckoutCustomizationProps = {
598
+ showTax?: boolean;
599
+ buttonBgColor?: string;
600
+ buttonTextColor?: string;
601
+ buttonDisabledBgColor?: string;
602
+ buttonDisabledTextColor?: string;
603
+
604
+ primaryTextColor?: string;
605
+ secondaryTextColor?: string;
606
+
607
+ primaryBgColor?: string;
608
+ secondaryBgColor?: string;
609
+ borderColor?: string;
610
+ cardBgColor?: string;
611
+
612
+ errorColor?: string;
613
+ errorLightColor?: string;
614
+ warningColor?: string;
615
+ warningLightColor?: string;
616
+ successColor?: string;
617
+ successLightColor?: string;
618
+ };
@@ -0,0 +1,93 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+
4
+ /**
5
+ * Divides the given filePath string into directory part and fileName part
6
+ * @param path Path for the file
7
+ */
8
+ export function getFilePathParts(path: string) {
9
+ const componentFilePathParts = path.split("/");
10
+
11
+ if (componentFilePathParts.length > 1) {
12
+ const dirParts = componentFilePathParts.slice(
13
+ 0,
14
+ componentFilePathParts.length - 1
15
+ );
16
+ const filePart = componentFilePathParts[componentFilePathParts.length - 1];
17
+
18
+ return {
19
+ dirParts,
20
+ filePart,
21
+ };
22
+ }
23
+
24
+ return {
25
+ filePart: path,
26
+ };
27
+ }
28
+
29
+ /**
30
+ * Deletes the contents of the given directory, exluding the ignoreFiles
31
+ * @param dirPath Path for the directory
32
+ * @param ignoreFiles List of files to keep in directory. Does not accept recursive paths, only first level files
33
+ *
34
+ * @returns true for successfull operation, false otherwise
35
+ */
36
+ export async function deleteDirContent(
37
+ dirPath: string,
38
+ ignoreFiles?: string[]
39
+ ) {
40
+ try {
41
+ // const fs = await import("fs-extra");
42
+ const files = fs.readdirSync(dirPath);
43
+
44
+ files.forEach((file) => {
45
+ if (!ignoreFiles?.includes(file)) {
46
+ fs.unlinkSync(path.join(dirPath, file));
47
+ }
48
+ });
49
+
50
+ return true;
51
+ } catch (err) {
52
+ return false;
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Creates the given file and directories for the filePath
58
+ * @param basePath Base directory path for the file
59
+ * @param fileSubPath Filename or the sub directory path for the file to write
60
+ * @param fileStr File contents
61
+ *
62
+ * @returns true for successfull operation, false otherwise
63
+ */
64
+ export async function createFile(
65
+ basePath: string,
66
+ fileSubPath: string,
67
+ fileStr: string
68
+ ) {
69
+ try {
70
+ // const fs = await import("fs-extra");
71
+ let generatedFolderPath = basePath;
72
+
73
+ const pageFilePathParts = getFilePathParts(fileSubPath);
74
+ if (pageFilePathParts.dirParts?.length) {
75
+ generatedFolderPath = path.join(
76
+ generatedFolderPath,
77
+ ...pageFilePathParts.dirParts
78
+ );
79
+ }
80
+
81
+ if (!fs.existsSync(generatedFolderPath)) {
82
+ fs.mkdirSync(generatedFolderPath, { recursive: true });
83
+ }
84
+
85
+ const filePath = path.join(generatedFolderPath, pageFilePathParts.filePart);
86
+ fs.writeFileSync(filePath, fileStr);
87
+
88
+ return true;
89
+ } catch (err) {
90
+ console.error(err);
91
+ return false;
92
+ }
93
+ }