@imksh/create 1.0.28 → 1.0.31
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/package.json +1 -1
- package/src/utils/askTemplate.js +2 -1
- package/templates/layers/electron/base/electron/main.js +262 -0
- package/templates/layers/electron/base/electron/preload.js +37 -0
- package/templates/layers/electron/base/electron-builder.json5 +68 -0
- package/templates/layers/electron/javascript/_gitignore +38 -0
- package/templates/layers/electron/javascript/package.json +49 -0
- package/templates/layers/electron/javascript/src/components/layout/SidebarLayout.jsx +43 -0
- package/templates/layers/electron/javascript/src/components/ui/TitleBar.jsx +130 -0
- package/templates/layers/electron/javascript/src/config/appConfig.js +51 -0
- package/templates/layers/electron/javascript/src/hooks/useElectron.js +68 -0
- package/templates/layers/electron/javascript/src/main.jsx +17 -0
- package/templates/layers/electron/javascript/src/store/useUiStore.js +59 -0
- package/templates/layers/electron/javascript/vite.config.js +29 -0
- package/templates/layers/electron/typescript/_gitignore +38 -0
- package/templates/layers/electron/typescript/electron/main.ts +213 -0
- package/templates/layers/electron/typescript/electron/preload.ts +52 -0
- package/templates/layers/electron/typescript/package.json +52 -0
- package/templates/layers/electron/typescript/src/components/layout/SidebarLayout.tsx +42 -0
- package/templates/layers/electron/typescript/src/components/ui/TitleBar.tsx +120 -0
- package/templates/layers/electron/typescript/src/config/appConfig.ts +52 -0
- package/templates/layers/electron/typescript/src/hooks/useElectron.ts +68 -0
- package/templates/layers/electron/typescript/src/main.tsx +17 -0
- package/templates/layers/electron/typescript/src/store/useUiStore.ts +97 -0
- package/templates/layers/electron/typescript/src/vite-env.d.ts +13 -0
- package/templates/layers/electron/typescript/tsconfig.json +25 -0
- package/templates/layers/electron/typescript/tsconfig.node.json +11 -0
- package/templates/layers/electron/typescript/vite.config.ts +29 -0
- package/templates/layers/next/javascript/src/components/common/Breadcrumbs.jsx +44 -6
- package/templates/layers/next/javascript/src/components/common/Loading.jsx +1 -0
- package/templates/layers/next/javascript/src/components/common/LottieIcon.jsx +1 -0
- package/templates/layers/next/javascript/src/components/common/Pagination.jsx +170 -0
- package/templates/layers/next/javascript/src/components/common/SidebarModal.jsx +180 -0
- package/templates/layers/next/javascript/src/components/common/StatsCard.jsx +168 -0
- package/templates/layers/next/javascript/src/components/common/Table.jsx +191 -41
- package/templates/layers/next/javascript/src/components/common/Tabs.jsx +187 -0
- package/templates/layers/next/javascript/src/components/common/ToggleSwitch.jsx +4 -3
- package/templates/layers/next/javascript/src/components/layout/ProtectedRoute.jsx +2 -1
- package/templates/layers/next/javascript/src/components/layout/PublicLayout.jsx +3 -6
- package/templates/layers/next/javascript/src/components/layout/SidebarLayout.jsx +4 -17
- package/templates/layers/next/javascript/src/components/modals/ConfirmModal.jsx +4 -12
- package/templates/layers/next/javascript/src/components/modals/Modal.jsx +50 -19
- package/templates/layers/next/javascript/src/components/ui/Input.jsx +50 -0
- package/templates/layers/next/{typescript/src/components/ui/sidebar.tsx → javascript/src/components/ui/Sidebar.jsx} +65 -53
- package/templates/layers/next/javascript/src/components/ui/SidebarHeader.jsx +11 -6
- package/templates/layers/next/javascript/src/config/appConfig.js +4 -4
- package/templates/layers/next/javascript/src/hooks/useWindowSize.js +2 -3
- package/templates/layers/next/javascript/src/store/useUiStore.js +9 -4
- package/templates/layers/next/typescript/src/components/common/Breadcrumbs.tsx +57 -8
- package/templates/layers/next/typescript/src/components/common/Loading.tsx +1 -0
- package/templates/layers/next/typescript/src/components/common/Pagination.tsx +186 -0
- package/templates/layers/next/typescript/src/components/common/SidebarModal.tsx +200 -0
- package/templates/layers/next/typescript/src/components/common/StatsCard.tsx +232 -0
- package/templates/layers/next/typescript/src/components/common/Table.tsx +201 -35
- package/templates/layers/next/typescript/src/components/common/Tabs.tsx +190 -0
- package/templates/layers/next/typescript/src/components/common/ToggleSwitch.tsx +12 -8
- package/templates/layers/next/typescript/src/components/layout/PublicLayout.tsx +8 -6
- package/templates/layers/next/typescript/src/components/layout/SidebarLayout.tsx +8 -17
- package/templates/layers/next/typescript/src/components/modals/ConfirmModal.tsx +1 -0
- package/templates/layers/next/typescript/src/components/modals/Modal.tsx +67 -21
- package/templates/layers/next/typescript/src/components/ui/Button.tsx +1 -0
- package/templates/layers/next/typescript/src/components/ui/Input.tsx +40 -60
- package/templates/layers/next/{javascript/src/components/ui/sidebar.jsx → typescript/src/components/ui/Sidebar.tsx} +77 -44
- package/templates/layers/next/typescript/src/components/ui/SidebarHeader.tsx +16 -10
- package/templates/layers/next/typescript/src/config/appConfig.ts +4 -4
- package/templates/layers/next/typescript/src/hooks/useWindowSize.ts +2 -3
- package/templates/layers/next/typescript/src/store/useUiStore.ts +14 -4
- package/templates/layers/node/javascript/package.json +2 -1
- package/templates/layers/node/javascript/src/controllers/push.controller.js +35 -14
- package/templates/layers/node/javascript/src/models/pushSubscription.model.js +5 -0
- package/templates/layers/node/javascript/src/utils/pushHelper.js +59 -12
- package/templates/layers/node/typescript/package-lock.json +3795 -0
- package/templates/layers/node/typescript/package.json +3 -2
- package/templates/layers/node/typescript/src/controllers/push.controller.ts +35 -14
- package/templates/layers/node/typescript/src/models/pushSubscription.model.ts +6 -0
- package/templates/layers/node/typescript/src/services/auth.service.ts +3 -3
- package/templates/layers/node/typescript/src/utils/pushHelper.ts +66 -12
- package/templates/layers/node-prisma/javascript/package.json +6 -3
- package/templates/layers/node-prisma/javascript/prisma/schema.prisma +20 -9
- package/templates/layers/node-prisma/javascript/prisma.config.js +12 -0
- package/templates/layers/node-prisma/javascript/src/config/{db.js → prisma.js} +9 -1
- package/templates/layers/node-prisma/javascript/src/controllers/push.controller.js +58 -19
- package/templates/layers/node-prisma/javascript/src/utils/pushHelper.js +62 -14
- package/templates/layers/node-prisma/typescript/package-lock.json +4808 -0
- package/templates/layers/node-prisma/typescript/package.json +8 -4
- package/templates/layers/node-prisma/typescript/prisma/schema.prisma +20 -9
- package/templates/layers/node-prisma/typescript/prisma.config.ts +12 -0
- package/templates/layers/node-prisma/typescript/src/config/{db.ts → prisma.ts} +9 -1
- package/templates/layers/node-prisma/typescript/src/controllers/push.controller.ts +67 -22
- package/templates/layers/node-prisma/typescript/src/index.ts +1 -1
- package/templates/layers/node-prisma/typescript/src/middleware/auth.middleware.ts +15 -5
- package/templates/layers/node-prisma/typescript/src/services/auth.service.ts +134 -128
- package/templates/layers/node-prisma/typescript/src/utils/pushHelper.ts +69 -14
- package/templates/layers/prisma/typescript/prisma/schema.prisma +35 -10
- package/templates/layers/react/javascript/src/components/common/Breadcrumbs.jsx +62 -58
- package/templates/layers/react/javascript/src/components/common/Pagination.jsx +164 -76
- package/templates/layers/react/javascript/src/components/common/SidebarModal.jsx +179 -0
- package/templates/layers/react/javascript/src/components/common/StatsCard.jsx +167 -0
- package/templates/layers/react/javascript/src/components/common/Table.jsx +248 -132
- package/templates/layers/react/javascript/src/components/common/Tabs.jsx +164 -112
- package/templates/layers/react/javascript/src/components/common/ToggleSwitch.jsx +3 -3
- package/templates/layers/react/javascript/src/components/layout/SidebarLayout.jsx +4 -12
- package/templates/layers/react/javascript/src/components/modals/Modal.jsx +53 -18
- package/templates/layers/react/javascript/src/components/ui/Input.jsx +49 -0
- package/templates/layers/react/javascript/src/components/ui/Sidebar.jsx +215 -0
- package/templates/layers/react/javascript/src/components/ui/SidebarHeader.jsx +25 -30
- package/templates/layers/react/javascript/src/config/appConfig.js +3 -3
- package/templates/layers/react/javascript/src/hooks/useWindowSize.js +2 -2
- package/templates/layers/react/typescript/src/components/common/Breadcrumbs.tsx +32 -6
- package/templates/layers/react/typescript/src/components/common/Pagination.tsx +151 -57
- package/templates/layers/react/typescript/src/components/common/SidebarModal.tsx +199 -0
- package/templates/layers/react/typescript/src/components/common/StatsCard.tsx +231 -0
- package/templates/layers/react/typescript/src/components/common/Table.tsx +197 -34
- package/templates/layers/react/typescript/src/components/common/Tabs.tsx +56 -12
- package/templates/layers/react/typescript/src/components/common/ToggleSwitch.tsx +15 -3
- package/templates/layers/react/typescript/src/components/layout/SidebarLayout.tsx +3 -6
- package/templates/layers/react/typescript/src/components/modals/Modal.tsx +151 -0
- package/templates/layers/react/typescript/src/components/ui/Input.tsx +58 -0
- package/templates/layers/react/typescript/src/components/ui/Sidebar.tsx +116 -53
- package/templates/layers/react/typescript/src/components/ui/SidebarHeader.tsx +5 -4
- package/templates/layers/react/typescript/src/config/appConfig.ts +3 -3
- package/templates/layers/react/typescript/src/hooks/useWindowSize.ts +2 -3
- package/templates/layers/react-native/base/src/components/ui/BiometricLock.tsx +2 -1
- package/templates/layers/react-native/base/src/config/appConfig.ts +44 -0
- package/templates/presets/electron/preset.json +9 -0
- package/templates/presets/electron-ts/preset.json +9 -0
- package/templates/layers/react/javascript/src/components/ui/sidebar.jsx +0 -169
|
@@ -6,26 +6,47 @@ export const subscribe = async (req, res, next) => {
|
|
|
6
6
|
const subscription = req.body;
|
|
7
7
|
const userId = req.user?._id || req.user?.id; // supports both mongoose and prisma IDs
|
|
8
8
|
|
|
9
|
-
if (!subscription
|
|
9
|
+
if (!subscription) {
|
|
10
10
|
return next({ status: 400, message: "Invalid subscription payload" });
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
const
|
|
13
|
+
const isExpo = !!subscription.token;
|
|
14
|
+
const isWeb = !!(subscription.endpoint && subscription.keys);
|
|
14
15
|
|
|
15
|
-
if (
|
|
16
|
-
|
|
17
|
-
existingSub.user = userId; await existingSub.save();
|
|
18
|
-
}
|
|
19
|
-
return res.status(200).json({ success: true, message: "Already subscribed." });
|
|
16
|
+
if (!isExpo && !isWeb) {
|
|
17
|
+
return next({ status: 400, message: "Missing token (EXPO) or endpoint/keys (WEB)" });
|
|
20
18
|
}
|
|
21
19
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
if (isExpo) {
|
|
21
|
+
const existingSub = await PushSubscription.findOne({ expoPushToken: subscription.token });
|
|
22
|
+
if (existingSub) {
|
|
23
|
+
if (userId && String(existingSub.user) !== String(userId)) {
|
|
24
|
+
existingSub.user = userId; await existingSub.save();
|
|
25
|
+
}
|
|
26
|
+
return res.status(200).json({ success: true, message: "Already subscribed." });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
await PushSubscription.create({
|
|
30
|
+
type: "EXPO",
|
|
31
|
+
expoPushToken: subscription.token,
|
|
32
|
+
user: userId || undefined
|
|
33
|
+
});
|
|
34
|
+
} else {
|
|
35
|
+
const existingSub = await PushSubscription.findOne({ endpoint: subscription.endpoint });
|
|
36
|
+
if (existingSub) {
|
|
37
|
+
if (userId && String(existingSub.user) !== String(userId)) {
|
|
38
|
+
existingSub.user = userId; await existingSub.save();
|
|
39
|
+
}
|
|
40
|
+
return res.status(200).json({ success: true, message: "Already subscribed." });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
await PushSubscription.create({
|
|
44
|
+
type: "WEB",
|
|
45
|
+
endpoint: subscription.endpoint,
|
|
46
|
+
keys: subscription.keys,
|
|
47
|
+
user: userId || undefined
|
|
48
|
+
});
|
|
49
|
+
}
|
|
29
50
|
|
|
30
51
|
res.status(201).json({ success: true, message: "Subscription created." });
|
|
31
52
|
} catch (error) {
|
|
@@ -3,6 +3,11 @@ import mongoose from "mongoose";
|
|
|
3
3
|
// Handles both Web Push (endpoint + keys) and Expo Push (expoPushToken)
|
|
4
4
|
const pushSubscriptionSchema = new mongoose.Schema(
|
|
5
5
|
{
|
|
6
|
+
type: {
|
|
7
|
+
type: String,
|
|
8
|
+
enum: ["WEB", "EXPO"],
|
|
9
|
+
default: "WEB",
|
|
10
|
+
},
|
|
6
11
|
// Web Push fields
|
|
7
12
|
endpoint: {
|
|
8
13
|
type: String,
|
|
@@ -1,20 +1,67 @@
|
|
|
1
1
|
import webpush from "../config/webPush.js";
|
|
2
|
+
import { Expo } from "expo-server-sdk";
|
|
2
3
|
import logger from "./logger.js";
|
|
3
4
|
import PushSubscription from "../models/pushSubscription.model.js";
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
const expo = new Expo();
|
|
7
|
+
|
|
8
|
+
export const sendPushToUser = async (
|
|
9
|
+
userId,
|
|
10
|
+
title,
|
|
11
|
+
body,
|
|
12
|
+
url = "/",
|
|
13
|
+
) => {
|
|
6
14
|
try {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
const subscriptions = await PushSubscription.find({ user: userId });
|
|
16
|
+
|
|
17
|
+
if (subscriptions.length === 0) return;
|
|
18
|
+
|
|
19
|
+
const webSubs = subscriptions.filter(s => s.type === "WEB");
|
|
20
|
+
const expoSubs = subscriptions.filter(s => s.type === "EXPO");
|
|
21
|
+
|
|
22
|
+
// Web Push
|
|
23
|
+
if (webSubs.length > 0) {
|
|
24
|
+
const payload = JSON.stringify({ title, body, url });
|
|
25
|
+
await Promise.allSettled(
|
|
26
|
+
webSubs.map(async (sub) => {
|
|
27
|
+
if (!sub.endpoint || !sub.keys) return;
|
|
28
|
+
const pushSub = { endpoint: sub.endpoint, keys: sub.keys };
|
|
29
|
+
try {
|
|
30
|
+
await webpush.sendNotification(pushSub, payload);
|
|
31
|
+
} catch (err) {
|
|
32
|
+
if (err.statusCode === 404 || err.statusCode === 410) {
|
|
33
|
+
await sub.deleteOne();
|
|
34
|
+
} else {
|
|
35
|
+
logger.error("Web Push Error", err);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
})
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Expo Push
|
|
43
|
+
if (expoSubs.length > 0) {
|
|
44
|
+
const messages = [];
|
|
45
|
+
for (const sub of expoSubs) {
|
|
46
|
+
if (!sub.expoPushToken || !Expo.isExpoPushToken(sub.expoPushToken)) continue;
|
|
47
|
+
messages.push({
|
|
48
|
+
to: sub.expoPushToken,
|
|
49
|
+
sound: "default",
|
|
50
|
+
title,
|
|
51
|
+
body,
|
|
52
|
+
data: { url },
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const chunks = expo.chunkPushNotifications(messages);
|
|
57
|
+
for (const chunk of chunks) {
|
|
58
|
+
try {
|
|
59
|
+
await expo.sendPushNotificationsAsync(chunk);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
logger.error("Error sending push notification chunk", error);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
18
65
|
} catch (error) {
|
|
19
66
|
logger.error("Error sending push notification to user", error);
|
|
20
67
|
}
|