@infuro/cms-core 1.0.45 → 1.0.46
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/README.md +19 -2
- package/dist/admin.cjs +873 -214
- package/dist/admin.d.cts +7 -1
- package/dist/admin.d.ts +7 -1
- package/dist/admin.js +874 -215
- package/dist/api.cjs +40 -37
- package/dist/api.d.cts +1 -1
- package/dist/api.d.ts +1 -1
- package/dist/api.js +8 -5
- package/dist/auth.cjs +23 -23
- package/dist/auth.d.cts +1 -0
- package/dist/auth.d.ts +1 -0
- package/dist/auth.js +2 -2
- package/dist/chunk-2KUCQVAQ.js +936 -0
- package/dist/chunk-3K5AIEIZ.js +256 -0
- package/dist/{chunk-I6NH72MO.js → chunk-57O3HZPG.js} +9 -1
- package/dist/chunk-7PMHZRF3.cjs +872 -0
- package/dist/chunk-BXYZDMTZ.cjs +953 -0
- package/dist/chunk-CQHXW4TR.js +107 -0
- package/dist/{chunk-NNQBWDCI.js → chunk-CRYKVJTO.js} +55 -959
- package/dist/chunk-DBPSJYLZ.js +47 -0
- package/dist/{chunk-TAHX46EI.cjs → chunk-FBKDMRQL.cjs} +9 -1
- package/dist/chunk-GUSHM5HN.js +862 -0
- package/dist/chunk-HY3AXLOI.cjs +265 -0
- package/dist/chunk-L3525VXI.js +243 -0
- package/dist/{chunk-ZMRQ72F6.cjs → chunk-NBY4NVTY.cjs} +3 -3
- package/dist/chunk-OY2YTBMP.cjs +50 -0
- package/dist/{chunk-BLR6H5GL.js → chunk-SF2XKMCI.js} +3 -3
- package/dist/{chunk-22FFHLTO.cjs → chunk-TCSGFAWB.cjs} +56 -970
- package/dist/{chunk-F5XFHYTG.cjs → chunk-UDVLFVEC.cjs} +661 -382
- package/dist/{chunk-MVXLRANV.js → chunk-UKC3HYXI.js} +591 -323
- package/dist/chunk-V25RDUOU.cjs +248 -0
- package/dist/chunk-XMRMZ6NQ.cjs +109 -0
- package/dist/cli.cjs +9 -4
- package/dist/cli.js +9 -4
- package/dist/{email-queue-TPZWLTIV.cjs → email-queue-6NJY6HNM.cjs} +7 -5
- package/dist/email-queue-OI2HSCGE.js +4 -0
- package/dist/erp-order-invoice-3GXDE443.js +3 -0
- package/dist/erp-order-invoice-EYYNR526.cjs +24 -0
- package/dist/index.cjs +391 -364
- package/dist/index.d.cts +267 -14
- package/dist/index.d.ts +267 -14
- package/dist/index.js +12 -110
- package/dist/migrations/1781810000000-OrderItemsVariantId.ts +44 -0
- package/dist/migrations/1781900000000-UserInviteStatusToken.ts +46 -0
- package/dist/migrations/1782000000000-ComboSlug.ts +58 -0
- package/dist/migrations/1782100000000-DiscountDeviceType.ts +20 -0
- package/dist/order-inventory-2MYRKEPC.cjs +39 -0
- package/dist/order-inventory-76V4XIGW.js +2 -0
- package/dist/order-notification-dispatcher-SBQAMM5V.cjs +21 -0
- package/dist/{order-notification-dispatcher-XWIJYDGA.js → order-notification-dispatcher-ZJZB2HUN.js} +5 -2
- package/dist/retire-soft-deleted-unique-5VXBA5XX.cjs +15 -0
- package/dist/retire-soft-deleted-unique-NXQIH4BC.js +2 -0
- package/dist/send-order-placed-emails-B5ZVJT7T.cjs +15 -0
- package/dist/send-order-placed-emails-WPI37KRZ.js +6 -0
- package/package.json +5 -4
- package/src/admin/admin.css +27 -24
- package/dist/chunk-5ELSW2UP.js +0 -150
- package/dist/chunk-PNOKNSG2.cjs +0 -222
- package/dist/chunk-WEMDMVHQ.js +0 -216
- package/dist/chunk-XW5ATPRW.cjs +0 -155
- package/dist/email-queue-CGZBVVAS.js +0 -2
- package/dist/erp-order-invoice-3YISSOWW.js +0 -3
- package/dist/erp-order-invoice-ZR5F2KTA.cjs +0 -12
- package/dist/order-notification-dispatcher-RU7BTGGX.cjs +0 -18
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
|
2
|
+
|
|
3
|
+
export class OrderItemsVariantId1781810000000 implements MigrationInterface {
|
|
4
|
+
name = 'OrderItemsVariantId1781810000000';
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(`
|
|
8
|
+
ALTER TABLE "order_items"
|
|
9
|
+
ADD COLUMN IF NOT EXISTS "variantId" integer
|
|
10
|
+
`);
|
|
11
|
+
await queryRunner.query(`
|
|
12
|
+
CREATE INDEX IF NOT EXISTS "IDX_order_items_variantId"
|
|
13
|
+
ON "order_items" ("variantId")
|
|
14
|
+
`);
|
|
15
|
+
// Best-effort FK when product_variants exists
|
|
16
|
+
await queryRunner.query(`
|
|
17
|
+
DO $$
|
|
18
|
+
BEGIN
|
|
19
|
+
IF EXISTS (
|
|
20
|
+
SELECT 1 FROM information_schema.tables
|
|
21
|
+
WHERE table_name = 'product_variants'
|
|
22
|
+
) AND NOT EXISTS (
|
|
23
|
+
SELECT 1 FROM information_schema.table_constraints
|
|
24
|
+
WHERE constraint_name = 'FK_order_items_variant'
|
|
25
|
+
) THEN
|
|
26
|
+
ALTER TABLE "order_items"
|
|
27
|
+
ADD CONSTRAINT "FK_order_items_variant"
|
|
28
|
+
FOREIGN KEY ("variantId") REFERENCES "product_variants"("id")
|
|
29
|
+
ON DELETE SET NULL ON UPDATE NO ACTION;
|
|
30
|
+
END IF;
|
|
31
|
+
END $$;
|
|
32
|
+
`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
36
|
+
await queryRunner.query(`
|
|
37
|
+
ALTER TABLE "order_items" DROP CONSTRAINT IF EXISTS "FK_order_items_variant"
|
|
38
|
+
`);
|
|
39
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_order_items_variantId"`);
|
|
40
|
+
await queryRunner.query(`
|
|
41
|
+
ALTER TABLE "order_items" DROP COLUMN IF EXISTS "variantId"
|
|
42
|
+
`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
|
2
|
+
|
|
3
|
+
export class UserInviteStatusToken1781900000000 implements MigrationInterface {
|
|
4
|
+
name = 'UserInviteStatusToken1781900000000';
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(`
|
|
8
|
+
DO $$ BEGIN
|
|
9
|
+
CREATE TYPE "users_invitestatus_enum" AS ENUM ('pending', 'active');
|
|
10
|
+
EXCEPTION WHEN duplicate_object THEN NULL;
|
|
11
|
+
END $$
|
|
12
|
+
`);
|
|
13
|
+
|
|
14
|
+
await queryRunner.query(`
|
|
15
|
+
ALTER TABLE "users"
|
|
16
|
+
ADD COLUMN IF NOT EXISTS "inviteStatus" "users_invitestatus_enum" NOT NULL DEFAULT 'active'
|
|
17
|
+
`);
|
|
18
|
+
await queryRunner.query(`
|
|
19
|
+
ALTER TABLE "users"
|
|
20
|
+
ADD COLUMN IF NOT EXISTS "inviteToken" character varying
|
|
21
|
+
`);
|
|
22
|
+
|
|
23
|
+
// Existing users with a password are active; password-less users are pending invites.
|
|
24
|
+
await queryRunner.query(`
|
|
25
|
+
UPDATE "users"
|
|
26
|
+
SET "inviteStatus" = CASE
|
|
27
|
+
WHEN "password" IS NOT NULL AND TRIM("password") <> '' THEN 'active'::"users_invitestatus_enum"
|
|
28
|
+
ELSE 'pending'::"users_invitestatus_enum"
|
|
29
|
+
END
|
|
30
|
+
WHERE "deleted" = false
|
|
31
|
+
`);
|
|
32
|
+
|
|
33
|
+
await queryRunner.query(`
|
|
34
|
+
CREATE INDEX IF NOT EXISTS "IDX_users_inviteToken"
|
|
35
|
+
ON "users" ("inviteToken")
|
|
36
|
+
WHERE "inviteToken" IS NOT NULL
|
|
37
|
+
`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
41
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "IDX_users_inviteToken"`);
|
|
42
|
+
await queryRunner.query(`ALTER TABLE "users" DROP COLUMN IF EXISTS "inviteToken"`);
|
|
43
|
+
await queryRunner.query(`ALTER TABLE "users" DROP COLUMN IF EXISTS "inviteStatus"`);
|
|
44
|
+
await queryRunner.query(`DROP TYPE IF EXISTS "users_invitestatus_enum"`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Add combos.slug (unique per vendor), backfill from name.
|
|
5
|
+
*/
|
|
6
|
+
export class ComboSlug1782000000000 implements MigrationInterface {
|
|
7
|
+
name = 'ComboSlug1782000000000';
|
|
8
|
+
|
|
9
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
10
|
+
await queryRunner.query(`
|
|
11
|
+
ALTER TABLE "combos"
|
|
12
|
+
ADD COLUMN IF NOT EXISTS "slug" character varying
|
|
13
|
+
`);
|
|
14
|
+
|
|
15
|
+
// Slugify name; empty → combo-{id}
|
|
16
|
+
await queryRunner.query(`
|
|
17
|
+
UPDATE "combos"
|
|
18
|
+
SET "slug" = CASE
|
|
19
|
+
WHEN NULLIF(TRIM(BOTH '-' FROM LOWER(REGEXP_REPLACE(COALESCE(TRIM("name"), ''), '[^a-zA-Z0-9]+', '-', 'g'))), '') IS NULL
|
|
20
|
+
THEN 'combo-' || "id"::text
|
|
21
|
+
ELSE TRIM(BOTH '-' FROM LOWER(REGEXP_REPLACE(COALESCE(TRIM("name"), ''), '[^a-zA-Z0-9]+', '-', 'g')))
|
|
22
|
+
END
|
|
23
|
+
WHERE "slug" IS NULL OR TRIM("slug") = ''
|
|
24
|
+
`);
|
|
25
|
+
|
|
26
|
+
// Deduplicate within vendor (append -id when collisions remain)
|
|
27
|
+
await queryRunner.query(`
|
|
28
|
+
WITH ranked AS (
|
|
29
|
+
SELECT
|
|
30
|
+
id,
|
|
31
|
+
"vendorId",
|
|
32
|
+
slug,
|
|
33
|
+
ROW_NUMBER() OVER (PARTITION BY "vendorId", slug ORDER BY id) AS rn
|
|
34
|
+
FROM "combos"
|
|
35
|
+
WHERE deleted = false OR deleted IS NULL
|
|
36
|
+
)
|
|
37
|
+
UPDATE "combos" c
|
|
38
|
+
SET slug = c.slug || '-' || c.id::text
|
|
39
|
+
FROM ranked r
|
|
40
|
+
WHERE c.id = r.id AND r.rn > 1
|
|
41
|
+
`);
|
|
42
|
+
|
|
43
|
+
await queryRunner.query(`
|
|
44
|
+
ALTER TABLE "combos"
|
|
45
|
+
ALTER COLUMN "slug" SET NOT NULL
|
|
46
|
+
`);
|
|
47
|
+
|
|
48
|
+
await queryRunner.query(`
|
|
49
|
+
CREATE UNIQUE INDEX IF NOT EXISTS "UQ_combos_vendor_slug"
|
|
50
|
+
ON "combos" ("vendorId", "slug")
|
|
51
|
+
`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
55
|
+
await queryRunner.query(`DROP INDEX IF EXISTS "UQ_combos_vendor_slug"`);
|
|
56
|
+
await queryRunner.query(`ALTER TABLE "combos" DROP COLUMN IF EXISTS "slug"`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { MigrationInterface, QueryRunner } from 'typeorm';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Add discount_rules.type value `deviceType` (Web / Mobile condition; admin-only for now).
|
|
5
|
+
*/
|
|
6
|
+
export class DiscountDeviceType1782100000000 implements MigrationInterface {
|
|
7
|
+
name = 'DiscountDeviceType1782100000000';
|
|
8
|
+
|
|
9
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
10
|
+
await queryRunner.query(`
|
|
11
|
+
ALTER TYPE "public"."discount_rules_type_enum"
|
|
12
|
+
ADD VALUE IF NOT EXISTS 'deviceType'
|
|
13
|
+
`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
17
|
+
// Postgres cannot easily remove a single enum value; leave as no-op.
|
|
18
|
+
void queryRunner;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkHY3AXLOI_cjs = require('./chunk-HY3AXLOI.cjs');
|
|
4
|
+
require('./chunk-USNT2KNT.cjs');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Object.defineProperty(exports, "deductInventoryForConfirmedOrder", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () { return chunkHY3AXLOI_cjs.deductInventoryForConfirmedOrder; }
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "mergeInventoryLines", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return chunkHY3AXLOI_cjs.mergeInventoryLines; }
|
|
15
|
+
});
|
|
16
|
+
Object.defineProperty(exports, "orderInventorySnapshotFromRow", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return chunkHY3AXLOI_cjs.orderInventorySnapshotFromRow; }
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(exports, "orderStatusHoldsStock", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
get: function () { return chunkHY3AXLOI_cjs.orderStatusHoldsStock; }
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "reconcileOrderInventoryBetweenSnapshots", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () { return chunkHY3AXLOI_cjs.reconcileOrderInventoryBetweenSnapshots; }
|
|
27
|
+
});
|
|
28
|
+
Object.defineProperty(exports, "restoreInventoryForCancelledOrder", {
|
|
29
|
+
enumerable: true,
|
|
30
|
+
get: function () { return chunkHY3AXLOI_cjs.restoreInventoryForCancelledOrder; }
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(exports, "validateInventoryForConfirmedOrderLines", {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
get: function () { return chunkHY3AXLOI_cjs.validateInventoryForConfirmedOrderLines; }
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(exports, "validateInventoryForOrderBecomingConfirmed", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function () { return chunkHY3AXLOI_cjs.validateInventoryForOrderBecomingConfirmed; }
|
|
39
|
+
});
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { deductInventoryForConfirmedOrder, mergeInventoryLines, orderInventorySnapshotFromRow, orderStatusHoldsStock, reconcileOrderInventoryBetweenSnapshots, restoreInventoryForCancelledOrder, validateInventoryForConfirmedOrderLines, validateInventoryForOrderBecomingConfirmed } from './chunk-3K5AIEIZ.js';
|
|
2
|
+
import './chunk-SHUYVCID.js';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk7PMHZRF3_cjs = require('./chunk-7PMHZRF3.cjs');
|
|
4
|
+
require('./chunk-TCSGFAWB.cjs');
|
|
5
|
+
require('./chunk-UCKN4BBY.cjs');
|
|
6
|
+
require('./chunk-V25RDUOU.cjs');
|
|
7
|
+
require('./chunk-BXYZDMTZ.cjs');
|
|
8
|
+
require('./chunk-OOTLNH63.cjs');
|
|
9
|
+
require('./chunk-UPLVMVRX.cjs');
|
|
10
|
+
require('./chunk-USNT2KNT.cjs');
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
Object.defineProperty(exports, "initWhatsappTriggerDispatcher", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () { return chunk7PMHZRF3_cjs.initWhatsappTriggerDispatcher; }
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "resendOrderNotification", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () { return chunk7PMHZRF3_cjs.resendOrderNotification; }
|
|
21
|
+
});
|
package/dist/{order-notification-dispatcher-XWIJYDGA.js → order-notification-dispatcher-ZJZB2HUN.js}
RENAMED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
export { initWhatsappTriggerDispatcher, resendOrderNotification } from './chunk-
|
|
1
|
+
export { initWhatsappTriggerDispatcher, resendOrderNotification } from './chunk-GUSHM5HN.js';
|
|
2
|
+
import './chunk-CRYKVJTO.js';
|
|
2
3
|
import './chunk-HCIRL37O.js';
|
|
3
|
-
import './chunk-
|
|
4
|
+
import './chunk-L3525VXI.js';
|
|
5
|
+
import './chunk-2KUCQVAQ.js';
|
|
4
6
|
import './chunk-CRFV5WJK.js';
|
|
7
|
+
import './chunk-JC6DLWTE.js';
|
|
5
8
|
import './chunk-SHUYVCID.js';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkOY2YTBMP_cjs = require('./chunk-OY2YTBMP.cjs');
|
|
4
|
+
require('./chunk-USNT2KNT.cjs');
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
Object.defineProperty(exports, "activeUniqueValueExists", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () { return chunkOY2YTBMP_cjs.activeUniqueValueExists; }
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "retireSoftDeletedUniqueValue", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return chunkOY2YTBMP_cjs.retireSoftDeletedUniqueValue; }
|
|
15
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkXMRMZ6NQ_cjs = require('./chunk-XMRMZ6NQ.cjs');
|
|
4
|
+
require('./chunk-TCSGFAWB.cjs');
|
|
5
|
+
require('./chunk-V25RDUOU.cjs');
|
|
6
|
+
require('./chunk-BXYZDMTZ.cjs');
|
|
7
|
+
require('./chunk-UPLVMVRX.cjs');
|
|
8
|
+
require('./chunk-USNT2KNT.cjs');
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
Object.defineProperty(exports, "sendOrderPlacedEmailsAfterConfirmation", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () { return chunkXMRMZ6NQ_cjs.sendOrderPlacedEmailsAfterConfirmation; }
|
|
15
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@infuro/cms-core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.46",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -49,11 +49,11 @@
|
|
|
49
49
|
"./admin.css": "./src/admin/admin.css"
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|
|
52
|
-
"build": "npm run build:js &&
|
|
53
|
-
"build:js": "cross-env NODE_OPTIONS=--max-old-space-size=8192 FAST_BUILD=1 DTS=false tsup && node scripts/prepend-admin-use-client.mjs",
|
|
52
|
+
"build": "npm run build:js && npm run build:types",
|
|
53
|
+
"build:js": "cross-env NODE_OPTIONS=--max-old-space-size=8192 FAST_BUILD=1 DTS=false tsup && node scripts/prepend-admin-use-client.mjs && shx mkdir -p dist/migrations && shx cp -r src/migrations/. dist/migrations/",
|
|
54
54
|
"build:types": "node scripts/build-types-parallel.mjs",
|
|
55
55
|
"build:release": "cross-env NODE_OPTIONS=--max-old-space-size=8192 DTS=false tsup && node scripts/prepend-admin-use-client.mjs && shx mkdir -p dist/migrations && shx cp -r src/migrations/. dist/migrations/ && npm run build:types",
|
|
56
|
-
"build:fast": "npm run build",
|
|
56
|
+
"build:fast": "npm run build:js",
|
|
57
57
|
"dev": "cross-env NODE_OPTIONS=--max-old-space-size=8192 FAST_BUILD=1 DTS=false tsup --watch",
|
|
58
58
|
"link": "npm run build:release && npm link",
|
|
59
59
|
"prepublishOnly": "npm run build:release",
|
|
@@ -131,6 +131,7 @@
|
|
|
131
131
|
"next-themes": "^0.2.1",
|
|
132
132
|
"nodemailer": "^7.0.7",
|
|
133
133
|
"papaparse": "^5.4.1",
|
|
134
|
+
"pdf-lib": "^1.17.1",
|
|
134
135
|
"pdf-parse": "^1.1.1",
|
|
135
136
|
"pg": "^8.20.0",
|
|
136
137
|
"pg-boss": ">=10.0.0",
|
package/src/admin/admin.css
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
/* Admin only: design tokens (sidebar, UI). No public-site tokens. */
|
|
1
|
+
/* Admin only: design tokens (sidebar, UI). No public-site tokens. Light mode only. */
|
|
2
2
|
|
|
3
3
|
@layer base {
|
|
4
4
|
:root {
|
|
5
|
+
color-scheme: light;
|
|
5
6
|
--background: 0 0% 100%;
|
|
6
7
|
--foreground: 0 0% 3.9%;
|
|
7
8
|
--card: 0 0% 100%;
|
|
@@ -31,33 +32,35 @@
|
|
|
31
32
|
--sidebar-border: 220 13% 91%;
|
|
32
33
|
--sidebar-ring: 217.2 91.2% 59.8%;
|
|
33
34
|
}
|
|
35
|
+
/* Dark mode disabled: mirror light tokens so host .dark does not flip admin CSS vars */
|
|
34
36
|
.dark {
|
|
35
|
-
|
|
36
|
-
--
|
|
37
|
-
--
|
|
38
|
-
--card
|
|
39
|
-
--
|
|
40
|
-
--popover
|
|
37
|
+
color-scheme: light;
|
|
38
|
+
--background: 0 0% 100%;
|
|
39
|
+
--foreground: 0 0% 3.9%;
|
|
40
|
+
--card: 0 0% 100%;
|
|
41
|
+
--card-foreground: 0 0% 3.9%;
|
|
42
|
+
--popover: 0 0% 100%;
|
|
43
|
+
--popover-foreground: 0 0% 3.9%;
|
|
41
44
|
--primary: 220 70% 50%;
|
|
42
45
|
--primary-foreground: 0 0% 100%;
|
|
43
|
-
--secondary: 0 0%
|
|
44
|
-
--secondary-foreground: 0 0%
|
|
45
|
-
--muted: 0 0%
|
|
46
|
-
--muted-foreground: 0 0%
|
|
47
|
-
--accent: 0 0%
|
|
48
|
-
--accent-foreground: 0 0%
|
|
49
|
-
--destructive: 0
|
|
46
|
+
--secondary: 0 0% 96.1%;
|
|
47
|
+
--secondary-foreground: 0 0% 9%;
|
|
48
|
+
--muted: 0 0% 96.1%;
|
|
49
|
+
--muted-foreground: 0 0% 45.1%;
|
|
50
|
+
--accent: 0 0% 96.1%;
|
|
51
|
+
--accent-foreground: 0 0% 9%;
|
|
52
|
+
--destructive: 0 84.2% 60.2%;
|
|
50
53
|
--destructive-foreground: 0 0% 98%;
|
|
51
|
-
--border: 0 0%
|
|
52
|
-
--input: 0 0%
|
|
53
|
-
--ring: 0 0%
|
|
54
|
-
--sidebar-background:
|
|
55
|
-
--sidebar-foreground: 240
|
|
56
|
-
--sidebar-primary:
|
|
57
|
-
--sidebar-primary-foreground: 0 0%
|
|
58
|
-
--sidebar-accent: 240
|
|
59
|
-
--sidebar-accent-foreground: 240
|
|
60
|
-
--sidebar-border:
|
|
54
|
+
--border: 0 0% 89.8%;
|
|
55
|
+
--input: 0 0% 89.8%;
|
|
56
|
+
--ring: 0 0% 3.9%;
|
|
57
|
+
--sidebar-background: 0 0% 98%;
|
|
58
|
+
--sidebar-foreground: 240 5.3% 26.1%;
|
|
59
|
+
--sidebar-primary: 240 5.9% 10%;
|
|
60
|
+
--sidebar-primary-foreground: 0 0% 98%;
|
|
61
|
+
--sidebar-accent: 240 4.8% 95.9%;
|
|
62
|
+
--sidebar-accent-foreground: 240 5.9% 10%;
|
|
63
|
+
--sidebar-border: 220 13% 91%;
|
|
61
64
|
--sidebar-ring: 217.2 91.2% 59.8%;
|
|
62
65
|
}
|
|
63
66
|
|
package/dist/chunk-5ELSW2UP.js
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import { __name } from './chunk-SHUYVCID.js';
|
|
2
|
-
|
|
3
|
-
// src/plugins/email/email-queue.ts
|
|
4
|
-
var EMAIL_QUEUE_NAME = "email";
|
|
5
|
-
function registerEmailQueueProcessor(cms) {
|
|
6
|
-
const queue = cms.getPlugin("queue");
|
|
7
|
-
const email = cms.getPlugin("email");
|
|
8
|
-
if (!queue || !email) return;
|
|
9
|
-
queue.registerProcessor(EMAIL_QUEUE_NAME, async (data) => {
|
|
10
|
-
const payload = data;
|
|
11
|
-
const { to, templateName, ctx, subject, html, text } = payload;
|
|
12
|
-
if (!to) return;
|
|
13
|
-
if (templateName && ctx) {
|
|
14
|
-
const rendered = email.renderTemplate(templateName, ctx);
|
|
15
|
-
await email.send({
|
|
16
|
-
to,
|
|
17
|
-
subject: rendered.subject,
|
|
18
|
-
html: rendered.html,
|
|
19
|
-
text: rendered.text
|
|
20
|
-
});
|
|
21
|
-
} else if (subject != null && html != null) {
|
|
22
|
-
await email.send({
|
|
23
|
-
to,
|
|
24
|
-
subject,
|
|
25
|
-
html,
|
|
26
|
-
text
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
__name(registerEmailQueueProcessor, "registerEmailQueueProcessor");
|
|
32
|
-
async function queueEmail(cms, payload) {
|
|
33
|
-
const queue = cms.getPlugin("queue");
|
|
34
|
-
if (queue) {
|
|
35
|
-
await queue.add(EMAIL_QUEUE_NAME, payload);
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
const email = cms.getPlugin("email");
|
|
39
|
-
if (email && payload.templateName && payload.ctx) {
|
|
40
|
-
const rendered = email.renderTemplate(payload.templateName, payload.ctx);
|
|
41
|
-
await email.send({
|
|
42
|
-
to: payload.to,
|
|
43
|
-
subject: rendered.subject,
|
|
44
|
-
html: rendered.html,
|
|
45
|
-
text: rendered.text
|
|
46
|
-
});
|
|
47
|
-
} else if (email && payload.subject != null && payload.html != null) {
|
|
48
|
-
await email.send({
|
|
49
|
-
to: payload.to,
|
|
50
|
-
subject: payload.subject,
|
|
51
|
-
html: payload.html,
|
|
52
|
-
text: payload.text
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
__name(queueEmail, "queueEmail");
|
|
57
|
-
async function queueOrderPlacedEmails(cms, payload) {
|
|
58
|
-
const { orderNumber, total, subtotal, tax, currency, customerName, customerEmail, salesTeamEmails, companyDetails, lineItems, billingAddress, shippingAddress } = payload;
|
|
59
|
-
const base = {
|
|
60
|
-
orderNumber,
|
|
61
|
-
total: total != null ? String(total) : void 0,
|
|
62
|
-
subtotal: subtotal != null ? String(subtotal) : void 0,
|
|
63
|
-
tax: tax != null ? String(tax) : void 0,
|
|
64
|
-
currency,
|
|
65
|
-
customerName,
|
|
66
|
-
companyDetails: companyDetails ?? {},
|
|
67
|
-
lineItems: lineItems ?? [],
|
|
68
|
-
billingAddress,
|
|
69
|
-
shippingAddress
|
|
70
|
-
};
|
|
71
|
-
const customerLower = customerEmail?.trim().toLowerCase() ?? "";
|
|
72
|
-
const jobs = [];
|
|
73
|
-
if (customerEmail?.trim()) {
|
|
74
|
-
jobs.push(queueEmail(cms, {
|
|
75
|
-
to: customerEmail.trim(),
|
|
76
|
-
templateName: "orderPlaced",
|
|
77
|
-
ctx: {
|
|
78
|
-
...base,
|
|
79
|
-
audience: "customer"
|
|
80
|
-
}
|
|
81
|
-
}));
|
|
82
|
-
}
|
|
83
|
-
const seen = /* @__PURE__ */ new Set();
|
|
84
|
-
for (const raw of salesTeamEmails) {
|
|
85
|
-
const to = raw.trim();
|
|
86
|
-
if (!to) continue;
|
|
87
|
-
const key = to.toLowerCase();
|
|
88
|
-
if (seen.has(key)) continue;
|
|
89
|
-
seen.add(key);
|
|
90
|
-
if (customerLower && key === customerLower) continue;
|
|
91
|
-
jobs.push(queueEmail(cms, {
|
|
92
|
-
to,
|
|
93
|
-
templateName: "orderPlaced",
|
|
94
|
-
ctx: {
|
|
95
|
-
...base,
|
|
96
|
-
audience: "sales",
|
|
97
|
-
internalCustomerEmail: customerEmail?.trim() || void 0
|
|
98
|
-
}
|
|
99
|
-
}));
|
|
100
|
-
}
|
|
101
|
-
await Promise.all(jobs);
|
|
102
|
-
}
|
|
103
|
-
__name(queueOrderPlacedEmails, "queueOrderPlacedEmails");
|
|
104
|
-
async function queueVendorOnboardEmails(cms, payload) {
|
|
105
|
-
const { vendorName, vendorSlug, ownerName, ownerEmail, activation, inviteLink, signInLink, kind = "vendor_onboard", notifyEmails, companyDetails, sendToOwner = true } = payload;
|
|
106
|
-
const base = {
|
|
107
|
-
vendorName,
|
|
108
|
-
vendorSlug,
|
|
109
|
-
ownerName,
|
|
110
|
-
ownerEmail,
|
|
111
|
-
activation,
|
|
112
|
-
inviteLink,
|
|
113
|
-
signInLink,
|
|
114
|
-
kind,
|
|
115
|
-
companyDetails: companyDetails ?? {}
|
|
116
|
-
};
|
|
117
|
-
const ownerLower = ownerEmail?.trim().toLowerCase() ?? "";
|
|
118
|
-
const jobs = [];
|
|
119
|
-
if (sendToOwner && ownerEmail?.trim()) {
|
|
120
|
-
jobs.push(queueEmail(cms, {
|
|
121
|
-
to: ownerEmail.trim(),
|
|
122
|
-
templateName: "vendorOnboarded",
|
|
123
|
-
ctx: {
|
|
124
|
-
...base,
|
|
125
|
-
audience: "owner"
|
|
126
|
-
}
|
|
127
|
-
}));
|
|
128
|
-
}
|
|
129
|
-
const seen = /* @__PURE__ */ new Set();
|
|
130
|
-
for (const raw of notifyEmails) {
|
|
131
|
-
const to = raw.trim();
|
|
132
|
-
if (!to) continue;
|
|
133
|
-
const key = to.toLowerCase();
|
|
134
|
-
if (seen.has(key)) continue;
|
|
135
|
-
seen.add(key);
|
|
136
|
-
if (ownerLower && key === ownerLower) continue;
|
|
137
|
-
jobs.push(queueEmail(cms, {
|
|
138
|
-
to,
|
|
139
|
-
templateName: "vendorOnboarded",
|
|
140
|
-
ctx: {
|
|
141
|
-
...base,
|
|
142
|
-
audience: "internal"
|
|
143
|
-
}
|
|
144
|
-
}));
|
|
145
|
-
}
|
|
146
|
-
await Promise.all(jobs);
|
|
147
|
-
}
|
|
148
|
-
__name(queueVendorOnboardEmails, "queueVendorOnboardEmails");
|
|
149
|
-
|
|
150
|
-
export { queueEmail, queueOrderPlacedEmails, queueVendorOnboardEmails, registerEmailQueueProcessor };
|