@posx/core 5.5.340 → 5.5.351
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/CLAUDE.md +23 -23
- package/LICENSE +21 -21
- package/README.md +85 -85
- package/build/index.d.ts +55 -53
- package/build/index.js +124 -79
- package/jest.config.cjs +36 -36
- package/jest.setup.cjs +80 -80
- package/package.json +1 -1
- package/package.publish.json +120 -120
- package/tsdown.config.ts +18 -18
- package/vite.config.ts +86 -86
package/build/index.js
CHANGED
|
@@ -2063,6 +2063,7 @@ var OrderConfig = class {
|
|
|
2063
2063
|
};
|
|
2064
2064
|
var OrderDisplaySystemConfig = class {
|
|
2065
2065
|
constructor() {
|
|
2066
|
+
_defineProperty(this, "enabled", false);
|
|
2066
2067
|
_defineProperty(this, "language", "en");
|
|
2067
2068
|
}
|
|
2068
2069
|
};
|
|
@@ -3039,23 +3040,49 @@ const getByPath = (obj, path) => {
|
|
|
3039
3040
|
if (!obj || !path) return void 0;
|
|
3040
3041
|
return path.split(".").reduce((o, k) => o?.[k], obj);
|
|
3041
3042
|
};
|
|
3043
|
+
const parseConditions = (args) => {
|
|
3044
|
+
const conditions = [];
|
|
3045
|
+
for (let i = 0; i < args.length - 1; i += 2) if (typeof args[i] === "string" && !isOptions(args[i + 1])) conditions.push({
|
|
3046
|
+
prop: args[i],
|
|
3047
|
+
value: args[i + 1]
|
|
3048
|
+
});
|
|
3049
|
+
return conditions;
|
|
3050
|
+
};
|
|
3051
|
+
/**
|
|
3052
|
+
* Find first object matching ALL conditions (AND logic)
|
|
3053
|
+
* {{findAnd categories "name" "Topping" "active" true}}
|
|
3054
|
+
*/
|
|
3055
|
+
const findAnd = function(collection, ...args) {
|
|
3056
|
+
if (!Array.isArray(collection)) return null;
|
|
3057
|
+
const conditions = parseConditions(args);
|
|
3058
|
+
return collection.find((item) => conditions.every((c) => getByPath(item, c.prop) === c.value)) || null;
|
|
3059
|
+
};
|
|
3042
3060
|
/**
|
|
3043
|
-
* Find first object
|
|
3044
|
-
* {{
|
|
3045
|
-
* {{lookup (findBy modifiers "item.category_uid" "imc_xxx") "item.name"}} - get item.name
|
|
3061
|
+
* Find first object matching ANY condition (OR logic)
|
|
3062
|
+
* {{findOr categories "name" "Topping" "name" "Topping one"}}
|
|
3046
3063
|
*/
|
|
3047
|
-
const
|
|
3064
|
+
const findOr = function(collection, ...args) {
|
|
3048
3065
|
if (!Array.isArray(collection)) return null;
|
|
3049
|
-
|
|
3066
|
+
const conditions = parseConditions(args);
|
|
3067
|
+
return collection.find((item) => conditions.some((c) => getByPath(item, c.prop) === c.value)) || null;
|
|
3050
3068
|
};
|
|
3051
3069
|
/**
|
|
3052
|
-
* Filter array
|
|
3053
|
-
* {{
|
|
3054
|
-
* {{lookup (filterBy modifiers "item.category_uid" "imc_xxx") 0}} - get first match
|
|
3070
|
+
* Filter array matching ALL conditions (AND logic)
|
|
3071
|
+
* {{filterAnd modifiers "item.category_uid" "imc_xxx" "price" 0}}
|
|
3055
3072
|
*/
|
|
3056
|
-
const
|
|
3073
|
+
const filterAnd = function(collection, ...args) {
|
|
3057
3074
|
if (!Array.isArray(collection)) return [];
|
|
3058
|
-
|
|
3075
|
+
const conditions = parseConditions(args);
|
|
3076
|
+
return collection.filter((item) => conditions.every((c) => getByPath(item, c.prop) === c.value));
|
|
3077
|
+
};
|
|
3078
|
+
/**
|
|
3079
|
+
* Filter array matching ANY condition (OR logic)
|
|
3080
|
+
* {{filterOr modifiers "name" "Topping" "name" "Topping one"}}
|
|
3081
|
+
*/
|
|
3082
|
+
const filterOr = function(collection, ...args) {
|
|
3083
|
+
if (!Array.isArray(collection)) return [];
|
|
3084
|
+
const conditions = parseConditions(args);
|
|
3085
|
+
return collection.filter((item) => conditions.some((c) => getByPath(item, c.prop) === c.value));
|
|
3059
3086
|
};
|
|
3060
3087
|
/**
|
|
3061
3088
|
* Returns the first truthy value, or default
|
|
@@ -3109,8 +3136,10 @@ const comparisonHelpers = {
|
|
|
3109
3136
|
contains,
|
|
3110
3137
|
includes,
|
|
3111
3138
|
in: inArray,
|
|
3112
|
-
|
|
3113
|
-
|
|
3139
|
+
findAnd,
|
|
3140
|
+
findOr,
|
|
3141
|
+
filterAnd,
|
|
3142
|
+
filterOr,
|
|
3114
3143
|
default: defaultValue,
|
|
3115
3144
|
neither,
|
|
3116
3145
|
ifEven,
|
|
@@ -3163,6 +3192,69 @@ function helpers(options) {
|
|
|
3163
3192
|
*/
|
|
3164
3193
|
var helpers_register_default = helpers;
|
|
3165
3194
|
|
|
3195
|
+
//#endregion
|
|
3196
|
+
//#region src/types/ods.type.ts
|
|
3197
|
+
var OrderDisplay = class extends AppCoreModel {
|
|
3198
|
+
constructor() {
|
|
3199
|
+
super();
|
|
3200
|
+
_defineProperty(this, "uid", ModelPrefix.OrderDisplaySystem + nanoid());
|
|
3201
|
+
_defineProperty(this, "order_number", "");
|
|
3202
|
+
_defineProperty(this, "status", OrderDisplayStatus.Preparing);
|
|
3203
|
+
}
|
|
3204
|
+
};
|
|
3205
|
+
let OrderDisplayStatus = /* @__PURE__ */ function(OrderDisplayStatus$1) {
|
|
3206
|
+
OrderDisplayStatus$1["Preparing"] = "preparing";
|
|
3207
|
+
OrderDisplayStatus$1["ReadyForPickup"] = "ready_for_pickup";
|
|
3208
|
+
return OrderDisplayStatus$1;
|
|
3209
|
+
}({});
|
|
3210
|
+
|
|
3211
|
+
//#endregion
|
|
3212
|
+
//#region src/services/ods.service.ts
|
|
3213
|
+
var OrderDisplayService = class extends AppRemoteService {
|
|
3214
|
+
constructor(http, db, options, moduleName = "order_displays", methodName = "order_display") {
|
|
3215
|
+
super();
|
|
3216
|
+
this.http = http;
|
|
3217
|
+
this.db = db;
|
|
3218
|
+
this.options = options;
|
|
3219
|
+
this.moduleName = moduleName;
|
|
3220
|
+
this.methodName = methodName;
|
|
3221
|
+
}
|
|
3222
|
+
async toPickUp(uid) {
|
|
3223
|
+
const orderDisplay = await this.getOne(uid);
|
|
3224
|
+
if (!orderDisplay) throw new SystemError("Display order not found");
|
|
3225
|
+
if (orderDisplay.status == "ready_for_pickup") throw new SystemError("Order is already ready for pickup");
|
|
3226
|
+
orderDisplay.status = OrderDisplayStatus.ReadyForPickup;
|
|
3227
|
+
orderDisplay.updated_at = /* @__PURE__ */ new Date();
|
|
3228
|
+
if (orderDisplay.id_in_server == 0) throw new SystemError("Order is not synced with server");
|
|
3229
|
+
await this.updateOne(orderDisplay.id_in_server, orderDisplay);
|
|
3230
|
+
return orderDisplay;
|
|
3231
|
+
}
|
|
3232
|
+
async toPreparing(uid) {
|
|
3233
|
+
const orderDisplay = await this.getOne(uid);
|
|
3234
|
+
if (!orderDisplay) throw new SystemError("Display order not found");
|
|
3235
|
+
if (orderDisplay.status == "preparing") throw new SystemError("Order is already preparing");
|
|
3236
|
+
orderDisplay.status = OrderDisplayStatus.Preparing;
|
|
3237
|
+
orderDisplay.updated_at = /* @__PURE__ */ new Date();
|
|
3238
|
+
if (orderDisplay.id_in_server == 0) throw new SystemError("Order is not synced with server");
|
|
3239
|
+
await this.updateOne(orderDisplay.id_in_server, orderDisplay);
|
|
3240
|
+
return orderDisplay;
|
|
3241
|
+
}
|
|
3242
|
+
async undo() {
|
|
3243
|
+
const orderDisplays = await this.db.table(this.moduleName).filter((x) => x.status == OrderDisplayStatus.ReadyForPickup).reverse().limit(100).toArray();
|
|
3244
|
+
if (orderDisplays.length === 0) throw new SystemError("No order to undo");
|
|
3245
|
+
orderDisplays.sort((a, b) => {
|
|
3246
|
+
const dateA = new Date(a.updated_at).getTime();
|
|
3247
|
+
return new Date(b.updated_at).getTime() - dateA;
|
|
3248
|
+
});
|
|
3249
|
+
const latestOrderDisplay = orderDisplays[0];
|
|
3250
|
+
latestOrderDisplay.status = OrderDisplayStatus.Preparing;
|
|
3251
|
+
latestOrderDisplay.updated_at = /* @__PURE__ */ new Date();
|
|
3252
|
+
if (latestOrderDisplay.id_in_server == 0) throw new SystemError("Order is not synced with server");
|
|
3253
|
+
await this.updateOne(latestOrderDisplay.id_in_server, latestOrderDisplay);
|
|
3254
|
+
return latestOrderDisplay;
|
|
3255
|
+
}
|
|
3256
|
+
};
|
|
3257
|
+
|
|
3166
3258
|
//#endregion
|
|
3167
3259
|
//#region src/services/invoice.service.ts
|
|
3168
3260
|
helpers_register_default({ handlebars: Handlebars });
|
|
@@ -3186,6 +3278,7 @@ var InvoiceBaseService = class extends AppRemoteService {
|
|
|
3186
3278
|
_defineProperty(this, "printerService", void 0);
|
|
3187
3279
|
_defineProperty(this, "printJobService", void 0);
|
|
3188
3280
|
_defineProperty(this, "itemService", void 0);
|
|
3281
|
+
_defineProperty(this, "orderDisplayService", void 0);
|
|
3189
3282
|
this.tillService = new TillService(http, db, options, "tills", "till");
|
|
3190
3283
|
this.sectionItemService = new SectionItemService(http, db, options, "section_items", "section_item");
|
|
3191
3284
|
this.configService = new ConfigService(http, db, options, "configs", "config");
|
|
@@ -3193,6 +3286,7 @@ var InvoiceBaseService = class extends AppRemoteService {
|
|
|
3193
3286
|
this.printerService = new PrinterService(http, db, options, "printers", "printer");
|
|
3194
3287
|
this.printJobService = new PrintJobService(http, db, options, "print_jobs", "print_job");
|
|
3195
3288
|
this.itemService = new ItemService(http, db, options, "items", "item");
|
|
3289
|
+
this.orderDisplayService = new OrderDisplayService(http, db, options);
|
|
3196
3290
|
}
|
|
3197
3291
|
calculate(invoice, appConfig, disableRounding = false) {
|
|
3198
3292
|
if (invoice.lines == null || invoice.lines.length < 1) {
|
|
@@ -3940,7 +4034,8 @@ var InvoiceOperationService = class extends LineOperationService {
|
|
|
3940
4034
|
sectionItem.status = SectionItemStatus.CLOSED;
|
|
3941
4035
|
this.addEmployeeToInvoice(invoice, employee);
|
|
3942
4036
|
invoice.paid_at = /* @__PURE__ */ new Date();
|
|
3943
|
-
const
|
|
4037
|
+
const config = (await this.configService.getDefaultOne()).config;
|
|
4038
|
+
const datetimeFormat = config?.order?.datetime_format;
|
|
3944
4039
|
invoice.humanized_paid_at = humanizedData(invoice.paid_at, datetimeFormat);
|
|
3945
4040
|
invoice.payment_has_cash = invoice.payments?.some((payment) => payment.payment_method?.is_cash === true);
|
|
3946
4041
|
const stockChanges = await this.getStockChangeList(invoice, false);
|
|
@@ -3982,7 +4077,13 @@ var InvoiceOperationService = class extends LineOperationService {
|
|
|
3982
4077
|
this.sectionItemService.saveOne(res.data);
|
|
3983
4078
|
options.section_item = res.data;
|
|
3984
4079
|
throw new SystemError(`${res.error}, system has updated the data and please try again`);
|
|
3985
|
-
}
|
|
4080
|
+
}
|
|
4081
|
+
if (stockChanges.length > 0) await this.itemService.changeItemsStock(stockChanges);
|
|
4082
|
+
if (invoice.call_num && config?.ods?.enabled) {
|
|
4083
|
+
const orderDisplay = new OrderDisplay();
|
|
4084
|
+
orderDisplay.order_number = invoice.call_num;
|
|
4085
|
+
await this.orderDisplayService.addOne(orderDisplay);
|
|
4086
|
+
}
|
|
3986
4087
|
return options;
|
|
3987
4088
|
} catch (error) {
|
|
3988
4089
|
invoice.kitchen_print_job_uids.length = previousKitchenUidsLength;
|
|
@@ -3994,7 +4095,8 @@ var InvoiceOperationService = class extends LineOperationService {
|
|
|
3994
4095
|
invoice.status = InvoiceStatus.Paid;
|
|
3995
4096
|
if (employee != null) this.addEmployeeToInvoice(invoice, employee);
|
|
3996
4097
|
invoice.paid_at = /* @__PURE__ */ new Date();
|
|
3997
|
-
const
|
|
4098
|
+
const config = (await this.configService.getDefaultOne()).config;
|
|
4099
|
+
const datetimeFormat = config?.order?.datetime_format;
|
|
3998
4100
|
invoice.humanized_paid_at = humanizedData(invoice.paid_at, datetimeFormat);
|
|
3999
4101
|
invoice.created_at = /* @__PURE__ */ new Date();
|
|
4000
4102
|
invoice.created_at_timestamp = invoice.created_at.getTime();
|
|
@@ -4035,7 +4137,13 @@ var InvoiceOperationService = class extends LineOperationService {
|
|
|
4035
4137
|
this.saveOne(res.data);
|
|
4036
4138
|
options.invoice = res.data;
|
|
4037
4139
|
throw new SystemError(res.error);
|
|
4038
|
-
}
|
|
4140
|
+
}
|
|
4141
|
+
if (stockChanges.length > 0) await this.itemService.changeItemsStock(stockChanges);
|
|
4142
|
+
if (invoice.call_num && config?.ods?.enabled) {
|
|
4143
|
+
const orderDisplay = new OrderDisplay();
|
|
4144
|
+
orderDisplay.order_number = invoice.call_num;
|
|
4145
|
+
await this.orderDisplayService.addOne(orderDisplay);
|
|
4146
|
+
}
|
|
4039
4147
|
return options;
|
|
4040
4148
|
}
|
|
4041
4149
|
async voidInvoice(invoice, till, reason, employee) {
|
|
@@ -5679,69 +5787,6 @@ function createInstance(baseURL, uid, token) {
|
|
|
5679
5787
|
return instance;
|
|
5680
5788
|
}
|
|
5681
5789
|
|
|
5682
|
-
//#endregion
|
|
5683
|
-
//#region src/types/ods.type.ts
|
|
5684
|
-
var OrderDisplay = class extends AppCoreModel {
|
|
5685
|
-
constructor() {
|
|
5686
|
-
super();
|
|
5687
|
-
_defineProperty(this, "uid", ModelPrefix.OrderDisplaySystem + nanoid());
|
|
5688
|
-
_defineProperty(this, "order_number", "");
|
|
5689
|
-
_defineProperty(this, "status", OrderDisplayStatus.Preparing);
|
|
5690
|
-
}
|
|
5691
|
-
};
|
|
5692
|
-
let OrderDisplayStatus = /* @__PURE__ */ function(OrderDisplayStatus$1) {
|
|
5693
|
-
OrderDisplayStatus$1["Preparing"] = "preparing";
|
|
5694
|
-
OrderDisplayStatus$1["ReadyForPickup"] = "ready_for_pickup";
|
|
5695
|
-
return OrderDisplayStatus$1;
|
|
5696
|
-
}({});
|
|
5697
|
-
|
|
5698
|
-
//#endregion
|
|
5699
|
-
//#region src/services/ods.service.ts
|
|
5700
|
-
var OrderDisplayService = class extends AppRemoteService {
|
|
5701
|
-
constructor(http, db, options, moduleName = "order_displays", methodName = "order_display") {
|
|
5702
|
-
super();
|
|
5703
|
-
this.http = http;
|
|
5704
|
-
this.db = db;
|
|
5705
|
-
this.options = options;
|
|
5706
|
-
this.moduleName = moduleName;
|
|
5707
|
-
this.methodName = methodName;
|
|
5708
|
-
}
|
|
5709
|
-
async toPickUp(uid) {
|
|
5710
|
-
const orderDisplay = await this.getOne(uid);
|
|
5711
|
-
if (!orderDisplay) throw new SystemError("Display order not found");
|
|
5712
|
-
if (orderDisplay.status == "ready_for_pickup") throw new SystemError("Order is already ready for pickup");
|
|
5713
|
-
orderDisplay.status = OrderDisplayStatus.ReadyForPickup;
|
|
5714
|
-
orderDisplay.updated_at = /* @__PURE__ */ new Date();
|
|
5715
|
-
if (orderDisplay.id_in_server == 0) throw new SystemError("Order is not synced with server");
|
|
5716
|
-
await this.updateOne(orderDisplay.id_in_server, orderDisplay);
|
|
5717
|
-
return orderDisplay;
|
|
5718
|
-
}
|
|
5719
|
-
async toPreparing(uid) {
|
|
5720
|
-
const orderDisplay = await this.getOne(uid);
|
|
5721
|
-
if (!orderDisplay) throw new SystemError("Display order not found");
|
|
5722
|
-
if (orderDisplay.status == "preparing") throw new SystemError("Order is already preparing");
|
|
5723
|
-
orderDisplay.status = OrderDisplayStatus.Preparing;
|
|
5724
|
-
orderDisplay.updated_at = /* @__PURE__ */ new Date();
|
|
5725
|
-
if (orderDisplay.id_in_server == 0) throw new SystemError("Order is not synced with server");
|
|
5726
|
-
await this.updateOne(orderDisplay.id_in_server, orderDisplay);
|
|
5727
|
-
return orderDisplay;
|
|
5728
|
-
}
|
|
5729
|
-
async undo() {
|
|
5730
|
-
const orderDisplays = await this.db.table(this.moduleName).filter((x) => x.status == OrderDisplayStatus.ReadyForPickup).reverse().limit(100).toArray();
|
|
5731
|
-
if (orderDisplays.length === 0) throw new SystemError("No order to undo");
|
|
5732
|
-
orderDisplays.sort((a, b) => {
|
|
5733
|
-
const dateA = new Date(a.updated_at).getTime();
|
|
5734
|
-
return new Date(b.updated_at).getTime() - dateA;
|
|
5735
|
-
});
|
|
5736
|
-
const latestOrderDisplay = orderDisplays[0];
|
|
5737
|
-
latestOrderDisplay.status = OrderDisplayStatus.Preparing;
|
|
5738
|
-
latestOrderDisplay.updated_at = /* @__PURE__ */ new Date();
|
|
5739
|
-
if (latestOrderDisplay.id_in_server == 0) throw new SystemError("Order is not synced with server");
|
|
5740
|
-
await this.updateOne(latestOrderDisplay.id_in_server, latestOrderDisplay);
|
|
5741
|
-
return latestOrderDisplay;
|
|
5742
|
-
}
|
|
5743
|
-
};
|
|
5744
|
-
|
|
5745
5790
|
//#endregion
|
|
5746
5791
|
//#region src/service.factory.ts
|
|
5747
5792
|
const serviceProvider = new Map([
|
package/jest.config.cjs
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
// jest.config.js
|
|
2
|
-
module.exports = {
|
|
3
|
-
preset: 'ts-jest',
|
|
4
|
-
testEnvironment: 'jsdom',
|
|
5
|
-
setupFilesAfterEnv: ['<rootDir>/jest.setup.cjs'],
|
|
6
|
-
transform: {
|
|
7
|
-
'^.+\\.ts$': ['ts-jest', {
|
|
8
|
-
tsconfig: {
|
|
9
|
-
module: 'commonjs',
|
|
10
|
-
esModuleInterop: true,
|
|
11
|
-
}
|
|
12
|
-
}],
|
|
13
|
-
'^.+\\.(mjs|js)$': ['ts-jest', {
|
|
14
|
-
tsconfig: {
|
|
15
|
-
allowJs: true,
|
|
16
|
-
module: 'commonjs',
|
|
17
|
-
esModuleInterop: true,
|
|
18
|
-
}
|
|
19
|
-
}]
|
|
20
|
-
},
|
|
21
|
-
transformIgnorePatterns: [
|
|
22
|
-
'node_modules/(?!(.pnpm|nanoid|@litepos|dexie)/)', // Transform ESM packages
|
|
23
|
-
],
|
|
24
|
-
testMatch: [
|
|
25
|
-
'<rootDir>/src/test/**/*.test.ts'
|
|
26
|
-
],
|
|
27
|
-
moduleNameMapper: {
|
|
28
|
-
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/scripts/testMock.cjs',
|
|
29
|
-
'\\.(css|less)$': '<rootDir>/scripts/testMock.cjs',
|
|
30
|
-
'^nanoid$': '<rootDir>/src/test/__mocks__/nanoid.js',
|
|
31
|
-
'^dexie$': '<rootDir>/src/test/__mocks__/dexie.js',
|
|
32
|
-
'^@awesome-cordova-plugins/network-interface$': '<rootDir>/src/test/__mocks__/@awesome-cordova-plugins/network-interface.js',
|
|
33
|
-
'^canvas$': '<rootDir>/scripts/testMock.cjs'
|
|
34
|
-
},
|
|
35
|
-
moduleFileExtensions: ['web.js', 'js', 'web.ts', 'ts', 'web.tsx', 'tsx', 'json', 'web.jsx', 'jsx', 'node'],
|
|
36
|
-
};
|
|
1
|
+
// jest.config.js
|
|
2
|
+
module.exports = {
|
|
3
|
+
preset: 'ts-jest',
|
|
4
|
+
testEnvironment: 'jsdom',
|
|
5
|
+
setupFilesAfterEnv: ['<rootDir>/jest.setup.cjs'],
|
|
6
|
+
transform: {
|
|
7
|
+
'^.+\\.ts$': ['ts-jest', {
|
|
8
|
+
tsconfig: {
|
|
9
|
+
module: 'commonjs',
|
|
10
|
+
esModuleInterop: true,
|
|
11
|
+
}
|
|
12
|
+
}],
|
|
13
|
+
'^.+\\.(mjs|js)$': ['ts-jest', {
|
|
14
|
+
tsconfig: {
|
|
15
|
+
allowJs: true,
|
|
16
|
+
module: 'commonjs',
|
|
17
|
+
esModuleInterop: true,
|
|
18
|
+
}
|
|
19
|
+
}]
|
|
20
|
+
},
|
|
21
|
+
transformIgnorePatterns: [
|
|
22
|
+
'node_modules/(?!(.pnpm|nanoid|@litepos|dexie)/)', // Transform ESM packages
|
|
23
|
+
],
|
|
24
|
+
testMatch: [
|
|
25
|
+
'<rootDir>/src/test/**/*.test.ts'
|
|
26
|
+
],
|
|
27
|
+
moduleNameMapper: {
|
|
28
|
+
'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/scripts/testMock.cjs',
|
|
29
|
+
'\\.(css|less)$': '<rootDir>/scripts/testMock.cjs',
|
|
30
|
+
'^nanoid$': '<rootDir>/src/test/__mocks__/nanoid.js',
|
|
31
|
+
'^dexie$': '<rootDir>/src/test/__mocks__/dexie.js',
|
|
32
|
+
'^@awesome-cordova-plugins/network-interface$': '<rootDir>/src/test/__mocks__/@awesome-cordova-plugins/network-interface.js',
|
|
33
|
+
'^canvas$': '<rootDir>/scripts/testMock.cjs'
|
|
34
|
+
},
|
|
35
|
+
moduleFileExtensions: ['web.js', 'js', 'web.ts', 'ts', 'web.tsx', 'tsx', 'json', 'web.jsx', 'jsx', 'node'],
|
|
36
|
+
};
|
package/jest.setup.cjs
CHANGED
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
// Jest setup file to polyfill File and Blob APIs
|
|
2
|
-
// This ensures consistent behavior across different Node.js versions and test environments
|
|
3
|
-
|
|
4
|
-
// Polyfill Blob.text() if not available
|
|
5
|
-
if (typeof Blob !== 'undefined' && !Blob.prototype.text) {
|
|
6
|
-
Blob.prototype.text = async function() {
|
|
7
|
-
const reader = new FileReader();
|
|
8
|
-
return new Promise((resolve, reject) => {
|
|
9
|
-
reader.onload = () => resolve(reader.result);
|
|
10
|
-
reader.onerror = reject;
|
|
11
|
-
reader.readAsText(this);
|
|
12
|
-
});
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Polyfill FileReader if not available
|
|
17
|
-
if (typeof FileReader === 'undefined') {
|
|
18
|
-
global.FileReader = class FileReader {
|
|
19
|
-
result = null;
|
|
20
|
-
error = null;
|
|
21
|
-
onload = null;
|
|
22
|
-
onerror = null;
|
|
23
|
-
|
|
24
|
-
readAsText(blob) {
|
|
25
|
-
try {
|
|
26
|
-
// For our polyfilled Blob
|
|
27
|
-
if (blob.parts) {
|
|
28
|
-
this.result = blob.parts.join('');
|
|
29
|
-
} else if (typeof blob === 'string') {
|
|
30
|
-
this.result = blob;
|
|
31
|
-
} else {
|
|
32
|
-
this.result = String(blob);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (this.onload) {
|
|
36
|
-
setTimeout(() => this.onload({ target: this }), 0);
|
|
37
|
-
}
|
|
38
|
-
} catch (err) {
|
|
39
|
-
this.error = err;
|
|
40
|
-
if (this.onerror) {
|
|
41
|
-
setTimeout(() => this.onerror({ target: this }), 0);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Polyfill Blob if not available (for Node.js < 18)
|
|
49
|
-
if (typeof Blob === 'undefined') {
|
|
50
|
-
global.Blob = class Blob {
|
|
51
|
-
constructor(parts = [], options = {}) {
|
|
52
|
-
this.parts = parts;
|
|
53
|
-
this.type = options.type || '';
|
|
54
|
-
this.size = parts.reduce((acc, part) => {
|
|
55
|
-
return acc + (typeof part === 'string' ? part.length : part.length || 0);
|
|
56
|
-
}, 0);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async text() {
|
|
60
|
-
return this.parts.join('');
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
async arrayBuffer() {
|
|
64
|
-
const text = await this.text();
|
|
65
|
-
const buffer = Buffer.from(text);
|
|
66
|
-
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Polyfill File if not available (for Node.js < 18)
|
|
72
|
-
if (typeof File === 'undefined') {
|
|
73
|
-
global.File = class File extends global.Blob {
|
|
74
|
-
constructor(bits, name, options = {}) {
|
|
75
|
-
super(bits, options);
|
|
76
|
-
this.name = name;
|
|
77
|
-
this.lastModified = options.lastModified || Date.now();
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
}
|
|
1
|
+
// Jest setup file to polyfill File and Blob APIs
|
|
2
|
+
// This ensures consistent behavior across different Node.js versions and test environments
|
|
3
|
+
|
|
4
|
+
// Polyfill Blob.text() if not available
|
|
5
|
+
if (typeof Blob !== 'undefined' && !Blob.prototype.text) {
|
|
6
|
+
Blob.prototype.text = async function() {
|
|
7
|
+
const reader = new FileReader();
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
reader.onload = () => resolve(reader.result);
|
|
10
|
+
reader.onerror = reject;
|
|
11
|
+
reader.readAsText(this);
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Polyfill FileReader if not available
|
|
17
|
+
if (typeof FileReader === 'undefined') {
|
|
18
|
+
global.FileReader = class FileReader {
|
|
19
|
+
result = null;
|
|
20
|
+
error = null;
|
|
21
|
+
onload = null;
|
|
22
|
+
onerror = null;
|
|
23
|
+
|
|
24
|
+
readAsText(blob) {
|
|
25
|
+
try {
|
|
26
|
+
// For our polyfilled Blob
|
|
27
|
+
if (blob.parts) {
|
|
28
|
+
this.result = blob.parts.join('');
|
|
29
|
+
} else if (typeof blob === 'string') {
|
|
30
|
+
this.result = blob;
|
|
31
|
+
} else {
|
|
32
|
+
this.result = String(blob);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (this.onload) {
|
|
36
|
+
setTimeout(() => this.onload({ target: this }), 0);
|
|
37
|
+
}
|
|
38
|
+
} catch (err) {
|
|
39
|
+
this.error = err;
|
|
40
|
+
if (this.onerror) {
|
|
41
|
+
setTimeout(() => this.onerror({ target: this }), 0);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Polyfill Blob if not available (for Node.js < 18)
|
|
49
|
+
if (typeof Blob === 'undefined') {
|
|
50
|
+
global.Blob = class Blob {
|
|
51
|
+
constructor(parts = [], options = {}) {
|
|
52
|
+
this.parts = parts;
|
|
53
|
+
this.type = options.type || '';
|
|
54
|
+
this.size = parts.reduce((acc, part) => {
|
|
55
|
+
return acc + (typeof part === 'string' ? part.length : part.length || 0);
|
|
56
|
+
}, 0);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async text() {
|
|
60
|
+
return this.parts.join('');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async arrayBuffer() {
|
|
64
|
+
const text = await this.text();
|
|
65
|
+
const buffer = Buffer.from(text);
|
|
66
|
+
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Polyfill File if not available (for Node.js < 18)
|
|
72
|
+
if (typeof File === 'undefined') {
|
|
73
|
+
global.File = class File extends global.Blob {
|
|
74
|
+
constructor(bits, name, options = {}) {
|
|
75
|
+
super(bits, options);
|
|
76
|
+
this.name = name;
|
|
77
|
+
this.lastModified = options.lastModified || Date.now();
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|