adminforth 1.3.54-next.23 → 1.3.54-next.24

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.
Files changed (101) hide show
  1. package/dist/plugins/audit-log/types.js +2 -0
  2. package/dist/plugins/audit-log/types.js.map +1 -0
  3. package/dist/plugins/chat-gpt/types.js +2 -0
  4. package/dist/plugins/chat-gpt/types.js.map +1 -0
  5. package/dist/plugins/email-password-reset/types.js +2 -0
  6. package/dist/plugins/email-password-reset/types.js.map +1 -0
  7. package/dist/plugins/foreign-inline-list/types.js +2 -0
  8. package/dist/plugins/foreign-inline-list/types.js.map +1 -0
  9. package/dist/plugins/import-export/types.js +2 -0
  10. package/dist/plugins/import-export/types.js.map +1 -0
  11. package/dist/plugins/rich-editor/custom/async-queue.js +29 -0
  12. package/dist/plugins/rich-editor/custom/async-queue.js.map +1 -0
  13. package/dist/plugins/rich-editor/dist/async-queue.js +41 -0
  14. package/dist/plugins/rich-editor/dist/custom/async-queue.js +29 -0
  15. package/dist/plugins/rich-editor/dist/custom/async-queue.js.map +1 -0
  16. package/dist/plugins/rich-editor/types.js +16 -0
  17. package/dist/plugins/rich-editor/types.js.map +1 -0
  18. package/dist/plugins/two-factors-auth/types.js +2 -0
  19. package/dist/plugins/two-factors-auth/types.js.map +1 -0
  20. package/dist/plugins/upload/types.js +2 -0
  21. package/dist/plugins/upload/types.js.map +1 -0
  22. package/package.json +4 -1
  23. package/auth.ts +0 -140
  24. package/basePlugin.ts +0 -70
  25. package/dataConnectors/baseConnector.ts +0 -221
  26. package/dataConnectors/clickhouse.ts +0 -343
  27. package/dataConnectors/mongo.ts +0 -202
  28. package/dataConnectors/postgres.ts +0 -310
  29. package/dataConnectors/sqlite.ts +0 -258
  30. package/index.ts +0 -428
  31. package/modules/codeInjector.ts +0 -747
  32. package/modules/configValidator.ts +0 -588
  33. package/modules/operationalResource.ts +0 -98
  34. package/modules/restApi.ts +0 -718
  35. package/modules/styleGenerator.ts +0 -55
  36. package/modules/styles.ts +0 -126
  37. package/modules/utils.ts +0 -472
  38. package/servers/express.ts +0 -259
  39. package/spa/.eslintrc.cjs +0 -14
  40. package/spa/README.md +0 -39
  41. package/spa/env.d.ts +0 -1
  42. package/spa/index.html +0 -23
  43. package/spa/package-lock.json +0 -4659
  44. package/spa/package.json +0 -52
  45. package/spa/postcss.config.js +0 -6
  46. package/spa/public/assets/favicon.png +0 -0
  47. package/spa/src/App.vue +0 -418
  48. package/spa/src/assets/base.css +0 -2
  49. package/spa/src/assets/logo.svg +0 -19
  50. package/spa/src/components/AcceptModal.vue +0 -45
  51. package/spa/src/components/Breadcrumbs.vue +0 -41
  52. package/spa/src/components/BreadcrumbsWithButtons.vue +0 -26
  53. package/spa/src/components/CustomDatePicker.vue +0 -176
  54. package/spa/src/components/CustomDateRangePicker.vue +0 -218
  55. package/spa/src/components/CustomRangePicker.vue +0 -156
  56. package/spa/src/components/Dropdown.vue +0 -168
  57. package/spa/src/components/Filters.vue +0 -222
  58. package/spa/src/components/HelloWorld.vue +0 -17
  59. package/spa/src/components/MenuLink.vue +0 -27
  60. package/spa/src/components/ResourceForm.vue +0 -325
  61. package/spa/src/components/ResourceListTable.vue +0 -466
  62. package/spa/src/components/SingleSkeletLoader.vue +0 -13
  63. package/spa/src/components/SkeleteLoader.vue +0 -23
  64. package/spa/src/components/ThreeDotsMenu.vue +0 -43
  65. package/spa/src/components/Toast.vue +0 -78
  66. package/spa/src/components/ValueRenderer.vue +0 -141
  67. package/spa/src/components/icons/IconCalendar.vue +0 -5
  68. package/spa/src/components/icons/IconCommunity.vue +0 -7
  69. package/spa/src/components/icons/IconDocumentation.vue +0 -7
  70. package/spa/src/components/icons/IconEcosystem.vue +0 -7
  71. package/spa/src/components/icons/IconSupport.vue +0 -7
  72. package/spa/src/components/icons/IconTime.vue +0 -5
  73. package/spa/src/components/icons/IconTooling.vue +0 -19
  74. package/spa/src/composables/useFrontendApi.ts +0 -26
  75. package/spa/src/composables/useStores.ts +0 -131
  76. package/spa/src/index.scss +0 -31
  77. package/spa/src/main.ts +0 -18
  78. package/spa/src/renderers/CompactUUID.vue +0 -48
  79. package/spa/src/renderers/CountryFlag.vue +0 -69
  80. package/spa/src/router/index.ts +0 -59
  81. package/spa/src/spa_types/core.ts +0 -53
  82. package/spa/src/stores/core.ts +0 -148
  83. package/spa/src/stores/filters.ts +0 -27
  84. package/spa/src/stores/modal.ts +0 -48
  85. package/spa/src/stores/toast.ts +0 -31
  86. package/spa/src/stores/user.ts +0 -72
  87. package/spa/src/utils.ts +0 -160
  88. package/spa/src/views/CreateView.vue +0 -167
  89. package/spa/src/views/EditView.vue +0 -170
  90. package/spa/src/views/ListView.vue +0 -352
  91. package/spa/src/views/LoginView.vue +0 -192
  92. package/spa/src/views/ResourceParent.vue +0 -17
  93. package/spa/src/views/ShowView.vue +0 -194
  94. package/spa/tailwind.config.js +0 -17
  95. package/spa/tsconfig.app.json +0 -14
  96. package/spa/tsconfig.json +0 -11
  97. package/spa/tsconfig.node.json +0 -19
  98. package/spa/vite.config.ts +0 -56
  99. package/tsconfig.json +0 -112
  100. package/types/AdminForthConfig.ts +0 -1762
  101. package/types/FrontendAPI.ts +0 -143
@@ -1,55 +0,0 @@
1
- import { transformObject,deepMerge,createRGBA,parseColorForAliases,darkenRGBA, lightenRGBA, inverseRGBA } from "./utils.js";
2
- import { styles } from "./styles.js";
3
-
4
-
5
- export class StylesGenerator {
6
- styleConfig: any;
7
- defaultStyles: any;
8
-
9
- constructor(styleConfig: any) {
10
-
11
- this.styleConfig = styleConfig;
12
- this.defaultStyles = styles();
13
- }
14
-
15
- private generatePlainStyles(styleObj:any) {
16
- let plainCustomStyles = {}
17
- if (styleObj) {
18
- Object.keys(styleObj).forEach((k)=>{
19
- plainCustomStyles[k] = transformObject(styleObj[k])
20
- })
21
- }
22
- return plainCustomStyles;
23
- }
24
-
25
- private changeAlias(str:any, mergedStyles:any){
26
- const {aliasMatch,opacityMatch,darkenMatch,lightenMatch, inverseMatch} = parseColorForAliases(str);
27
- if (!aliasMatch) {
28
- return str;
29
- } else {
30
- const alias = aliasMatch[1];
31
- let opacity = opacityMatch ? parseFloat(opacityMatch[1]) : 1;
32
- const color = mergedStyles[alias];
33
- if (darkenMatch) {
34
- return darkenRGBA(createRGBA(color, opacity))
35
- }
36
- if (lightenMatch){
37
- return lightenRGBA(createRGBA(color, opacity))
38
- }
39
- if (inverseMatch){
40
- return inverseRGBA(createRGBA(color, opacity))
41
- }
42
- return createRGBA(color, opacity);
43
- }
44
- }
45
-
46
- mergeStyles() {
47
- let mergedStyles = deepMerge(this.defaultStyles, this.generatePlainStyles(this.styleConfig));
48
- let colors = mergedStyles.colors;
49
- Object.entries(colors).forEach(([key,value])=>{
50
-
51
- colors[key] = this.changeAlias(value,colors)
52
- })
53
- return mergedStyles;
54
- }
55
- }
package/modules/styles.ts DELETED
@@ -1,126 +0,0 @@
1
-
2
-
3
- export const styles = () => ({
4
- colors: {
5
- lightHtml: "#FFFFFF", // main background
6
-
7
- lightPrimary: "#1a56db", // primary color
8
- lightPrimaryContrast: "alias:lightPrimary inverse", // primary color contrast
9
- lightPrimaryOpacity: "alias:lightPrimary opacity:0.05", // primary color opacity
10
-
11
- lightNavbar: "#FFFFFF", // navbar background
12
- lightNavbarBorder: "rgb(229 231 235)", // border
13
- lightNavbarText: "#111827", // navbar text
14
- lightNavbarTextHover: "alias:lightNavbarText darken", // navbar text hover
15
- lightNavbarTextActive: "alias:lightNavbarText darken", // navbar text active
16
- lightNavbarIcons: "alias:lightNavbarText opacity:0.7", // navbar icons
17
- lightAnnouncementText: "alias:lightPrimaryContrast", // announcement text
18
- lightAnnouncementBG: "alias:lightPrimary", // announcement
19
-
20
- lightSidebar: "#f9fafb", // sidebar background
21
- lightSidebarBorder: "alias:lightSidebarText opacity:0.05", // sidebar right border
22
- lightSidebarItemHover: "alias:lightSidebarText opacity:0.05", // sidebar list item hover
23
- lightSidebarItemActive: "alias:lightSidebarText opacity:0.05", // sidebar list item active
24
- lightSidebarText: "#213045", // sidebar list item text
25
- lightSidebarTextHover: "alias:lightSidebarText darken", // sidebar list item text hover
26
- lightSidebarTextActive: "alias:lightSidebarText darken", // sidebar list item text active
27
- lightSidebarDevider: "alias:lightSidebarText opacity:0.3", // sidebar devider
28
- lightSidebarIcons: "alias:lightSidebarText opacity:0.7", // sidebar list item icons
29
- lightSidebarIconsHover: "alias:lightSidebarText", // sidebar list item icons hover
30
- lightSidebarHeading: "alias:lightSidebarText opacity:0.3", // sidebar heading
31
-
32
- lightList: "#FFFFFF", // list view background
33
- lightListTable: "#FFFFFF", // list view table background
34
- lightListTableHeading: "alias:lightListTableHeadingText opacity:0.04", // list view table heading
35
- lightListTableHeadingText: "#43445B", // list view table heading text
36
- lightListTableText: "#333333", // list view table text
37
- lightListTableRowHover: "rgb(249 250 251)", // list view row hover
38
- lightListBreadcrumbsText: "#666666", // list view breadcrumbs text
39
- lightListBorder: "#DDDDDD", // list view rows border
40
- // lightListButton: "#FFFFFF", // list view button
41
- // lightListButtonBorder: "#d1d5db", // list view button border
42
- // lightListButtonHover: "#f3f4f6", // list view button hover
43
- // lightListButtonBorderHover: "#f3f4f6", // list view button border hover
44
- // lightListButtonActive: "#f3f4f6", // list view button active
45
- // lightListButtonDisabled: "#f3f4f6", // list view button disabled
46
- // lightListButtonDisabledText: "#f3f4f6", // list view button disabled text
47
- // lightListButtonIcon: "#333333", // list view button icon
48
-
49
- lightForm: "#FFFFFF", // show view background
50
- lightFormBorder: "#F5F5F5", // show view rows border
51
- lightFormHeading: "alias:lightListTableHeading", // show view heading
52
-
53
- lightButtons: "#FFFFFF", // button background
54
- lightButtonsBorder: "#DDDDDD", // button border
55
- lightButtonsText: "#111827", // button text
56
- lightButtonsHover: "#f3f4f6", // button hover
57
- lightButtonsBorderHover: "#f3f4f6", // button border hover
58
- lightButtonsActive: "#f3f4f6", // button active
59
- lightButtonsDisabled: "#f3f4f6", // button disabled
60
- lightButtonsDisabledText: "#f3f4f6", // button disabled text
61
- lightButtonsIcon: "#333333", // button icon
62
-
63
-
64
-
65
- // colors for dark theme
66
- darkHtml: "#111827",
67
-
68
- darkPrimary: "rgb(130 172 255)", // primary color
69
- darkPrimaryContrast: "alias:darkPrimary inverse", // primary color contrast
70
- darkPrimaryOpacity: "#212A40", // primary color opacity
71
-
72
- darkNavbar: "#111827",
73
- darkNavbarBorder: "#e5e7eb",
74
- darkNavbarText: "#9ca3af",
75
- darkNavbarTextHover: "alias:darkNavbarText lighten",
76
- darkNavbarTextActive: "alias:darkNavbarText lighten",
77
- darkNavbarIcons: "alias:darkNavbarText opacity:0.7",
78
- darkAnnouncementText: "alias:darkPrimaryContrast",
79
- darkAnnouncementBG: "alias:darkPrimary",
80
-
81
- darkSidebar: "#1f2937",
82
- darkSidebarBorder: "alias:darkSidebarText opacity:0.3",
83
- darkSidebarItemHover: "alias:darkSidebarText opacity:0.1",
84
- darkSidebarItemActive: "alias:darkSidebarText opacity:0.4",
85
- darkSidebarText: "#9ca3af",
86
- darkSidebarTextHover: "alias:darkSidebarText lighten",
87
- darkSidebarTextActive: "alias:darkSidebarText lighten",
88
- darkSidebarDevider: "alias:darkSidebarText opacity:0.3",
89
- darkSidebarIcons: "alias:darkSidebarText opacity:0.7",
90
- darkSidebarIconsHover: "alias:darkSidebarText",
91
- darkSidebarHeading: "alias:darkSidebarText opacity:0.3",
92
-
93
-
94
- darkList: "#111111",
95
- darkListTable: "#1f2937",
96
- darkListTableHeading: "#334155",
97
- darkListTableHeadingText: "#9ca3af",
98
- darkListTableText: "#9ca3af",
99
- darkListTableRowHover: "rgb(35 47 65)",
100
- darkListBreadcrumbsText: "#BBBBBB",
101
- darkListBorder: "#444444",
102
-
103
- darkForm: "#111111",
104
- darkFormBorder: "#222222",
105
- darkFormHeading: "alias:darkListTableHeading"
106
-
107
- },
108
- boxShadow: {
109
- customLight: "0 4px 8px rgba(0, 0, 0, 0.1)", // Lighter shadow
110
- headerShadow: "0 4px 8px rgba(0, 0, 0, 0.1)", // Lighter shadow
111
- listTableShadow: "0 4px 8px rgba(0, 0, 0, 0.1)", // Lighter shadow
112
- darkListTableShadow: "0 4px 8px rgba(0, 0, 0, 0.3)", // Lighter shadow
113
- resourseFormShadow: "0 4px 8px rgba(0, 0, 0, 0.1)", // Lighter shadow
114
- darkResourseFormShadow: "0 4px 8px rgba(0, 0, 0, 0.3)", // Lighter shadow
115
-
116
- },
117
- fontSize: {
118
- "headerText-size": "1rem"
119
- },
120
- borderRadius: {
121
- "default": ".5rem"
122
- }
123
- });
124
-
125
-
126
-
package/modules/utils.ts DELETED
@@ -1,472 +0,0 @@
1
- import path from 'path';
2
- import { fileURLToPath } from 'url';
3
- import fs from 'fs';
4
- import Fuse from 'fuse.js';
5
- // @ts-ignore-next-line
6
-
7
-
8
- const csscolors = {
9
- "aliceblue": "#f0f8ff",
10
- "antiquewhite": "#faebd7",
11
- "aqua": "#00ffff",
12
- "aquamarine": "#7fffd4",
13
- "azure": "#f0ffff",
14
- "beige": "#f5f5dc",
15
- "bisque": "#ffe4c4",
16
- "black": "#000000",
17
- "blanchedalmond": "#ffebcd",
18
- "blue": "#0000ff",
19
- "blueviolet": "#8a2be2",
20
- "brown": "#a52a2a",
21
- "burlywood": "#deb887",
22
- "cadetblue": "#5f9ea0",
23
- "chartreuse": "#7fff00",
24
- "chocolate": "#d2691e",
25
- "coral": "#ff7f50",
26
- "cornflowerblue": "#6495ed",
27
- "cornsilk": "#fff8dc",
28
- "crimson": "#dc143c",
29
- "cyan": "#00ffff",
30
- "darkblue": "#00008b",
31
- "darkcyan": "#008b8b",
32
- "darkgoldenrod": "#b8860b",
33
- "darkgray": "#a9a9a9",
34
- "darkgreen": "#006400",
35
- "darkgrey": "#a9a9a9",
36
- "darkkhaki": "#bdb76b",
37
- "darkmagenta": "#8b008b",
38
- "darkolivegreen": "#556b2f",
39
- "darkorange": "#ff8c00",
40
- "darkorchid": "#9932cc",
41
- "darkred": "#8b0000",
42
- "darksalmon": "#e9967a",
43
- "darkseagreen": "#8fbc8f",
44
- "darkslateblue": "#483d8b",
45
- "darkslategray": "#2f4f4f",
46
- "darkslategrey": "#2f4f4f",
47
- "darkturquoise": "#00ced1",
48
- "darkviolet": "#9400d3",
49
- "deeppink": "#ff1493",
50
- "deepskyblue": "#00bfff",
51
- "dimgray": "#696969",
52
- "dimgrey": "#696969",
53
- "dodgerblue": "#1e90ff",
54
- "firebrick": "#b22222",
55
- "floralwhite": "#fffaf0",
56
- "forestgreen": "#228b22",
57
- "fuchsia": "#ff00ff",
58
- "gainsboro": "#dcdcdc",
59
- "ghostwhite": "#f8f8ff",
60
- "goldenrod": "#daa520",
61
- "gold": "#ffd700",
62
- "gray": "#808080",
63
- "green": "#008000",
64
- "greenyellow": "#adff2f",
65
- "grey": "#808080",
66
- "honeydew": "#f0fff0",
67
- "hotpink": "#ff69b4",
68
- "indianred": "#cd5c5c",
69
- "indigo": "#4b0082",
70
- "ivory": "#fffff0",
71
- "khaki": "#f0e68c",
72
- "lavenderblush": "#fff0f5",
73
- "lavender": "#e6e6fa",
74
- "lawngreen": "#7cfc00",
75
- "lemonchiffon": "#fffacd",
76
- "lightblue": "#add8e6",
77
- "lightcoral": "#f08080",
78
- "lightcyan": "#e0ffff",
79
- "lightgoldenrodyellow": "#fafad2",
80
- "lightgray": "#d3d3d3",
81
- "lightgreen": "#90ee90",
82
- "lightgrey": "#d3d3d3",
83
- "lightpink": "#ffb6c1",
84
- "lightsalmon": "#ffa07a",
85
- "lightseagreen": "#20b2aa",
86
- "lightskyblue": "#87cefa",
87
- "lightslategray": "#778899",
88
- "lightslategrey": "#778899",
89
- "lightsteelblue": "#b0c4de",
90
- "lightyellow": "#ffffe0",
91
- "lime": "#00ff00",
92
- "limegreen": "#32cd32",
93
- "linen": "#faf0e6",
94
- "magenta": "#ff00ff",
95
- "maroon": "#800000",
96
- "mediumaquamarine": "#66cdaa",
97
- "mediumblue": "#0000cd",
98
- "mediumorchid": "#ba55d3",
99
- "mediumpurple": "#9370db",
100
- "mediumseagreen": "#3cb371",
101
- "mediumslateblue": "#7b68ee",
102
- "mediumspringgreen": "#00fa9a",
103
- "mediumturquoise": "#48d1cc",
104
- "mediumvioletred": "#c71585",
105
- "midnightblue": "#191970",
106
- "mintcream": "#f5fffa",
107
- "mistyrose": "#ffe4e1",
108
- "moccasin": "#ffe4b5",
109
- "navajowhite": "#ffdead",
110
- "navy": "#000080",
111
- "oldlace": "#fdf5e6",
112
- "olive": "#808000",
113
- "olivedrab": "#6b8e23",
114
- "orange": "#ffa500",
115
- "orangered": "#ff4500",
116
- "orchid": "#da70d6",
117
- "palegoldenrod": "#eee8aa",
118
- "palegreen": "#98fb98",
119
- "paleturquoise": "#afeeee",
120
- "palevioletred": "#db7093",
121
- "papayawhip": "#ffefd5",
122
- "peachpuff": "#ffdab9",
123
- "peru": "#cd853f",
124
- "pink": "#ffc0cb",
125
- "plum": "#dda0dd",
126
- "powderblue": "#b0e0e6",
127
- "purple": "#800080",
128
- "rebeccapurple": "#663399",
129
- "red": "#ff0000",
130
- "rosybrown": "#bc8f8f",
131
- "royalblue": "#4169e1",
132
- "saddlebrown": "#8b4513",
133
- "salmon": "#fa8072",
134
- "sandybrown": "#f4a460",
135
- "seagreen": "#2e8b57",
136
- "seashell": "#fff5ee",
137
- "sienna": "#a0522d",
138
- "silver": "#c0c0c0",
139
- "skyblue": "#87ceeb",
140
- "slateblue": "#6a5acd",
141
- "slategray": "#708090",
142
- "slategrey": "#708090",
143
- "snow": "#fffafa",
144
- "springgreen": "#00ff7f",
145
- "steelblue": "#4682b4",
146
- "tan": "#d2b48c",
147
- "teal": "#008080",
148
- "thistle": "#d8bfd8",
149
- "tomato": "#ff6347",
150
- "turquoise": "#40e0d0",
151
- "violet": "#ee82ee",
152
- "wheat": "#f5deb3",
153
- "white": "#ffffff",
154
- "whitesmoke": "#f5f5f5",
155
- "yellow": "#ffff00",
156
- "yellowgreen": "#9acd32"
157
- }
158
-
159
-
160
-
161
- export function guessLabelFromName(name) {
162
- if (name.includes('_')) {
163
- return name.split('_').map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(' ');
164
- } else if (name.includes('-')) {
165
- return name.split('-').map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(' ');
166
- } else {
167
- // split by capital letters
168
- return name.split(/(?=[A-Z])/).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(' ');
169
- }
170
- }
171
-
172
- export const currentFileDir = (metaUrl) => {
173
- const __filename = fileURLToPath(metaUrl);
174
- let __dirname = path.dirname(__filename);
175
- if (__dirname.endsWith('/dist/modules')) {
176
- // in prod build we are in dist also, so make another back jump to go true sorces
177
- __dirname = path.join(__dirname, '..');
178
- }
179
- return __dirname;
180
- }
181
-
182
- // in both bundeled and dev mode this always points to the root of the adminforth package (where package.json is)
183
- export const ADMIN_FORTH_ABSOLUTE_PATH = path.join(currentFileDir(import.meta.url), '..');
184
-
185
- const package_json = JSON.parse(fs.readFileSync(path.join(ADMIN_FORTH_ABSOLUTE_PATH, 'package.json'), 'utf8'));
186
-
187
- export const ADMINFORTH_VERSION: string = package_json.version;
188
-
189
- export function getComponentNameFromPath(filePath) {
190
- return filePath.replace(/@/g, '').replace(/\./g, '').replace(/\//g, '');
191
- }
192
-
193
- export function listify(param?: Array<Function>) {
194
- return param || [];
195
- }
196
-
197
- export function deepMerge(target, source) {
198
- if (typeof target !== 'object' || target === null) {
199
- return source;
200
- }
201
-
202
- for (let key in source) {
203
- if (source.hasOwnProperty(key)) {
204
- if (typeof source[key] === 'object' && source[key] !== null) {
205
- if (!target[key]) {
206
- target[key] = {};
207
- }
208
- deepMerge(target[key], source[key]);
209
- } else {
210
- target[key] = source[key];
211
- }
212
- }
213
- }
214
-
215
- return target;
216
- }
217
-
218
- function toCamelCase(str) {
219
- return str.replace(/[-_](.)/g, (_, char) => char.toUpperCase());
220
- }
221
-
222
- export function transformObject(obj, parentKey = '', result = {}) {
223
- for (const key in obj) {
224
- if (obj.hasOwnProperty(key)) {
225
- const camelCaseKey = toCamelCase(parentKey ? `${parentKey}_${key}` : key);
226
- if (typeof obj[key] === 'object' && !Array.isArray(obj[key])) {
227
- transformObject(obj[key], camelCaseKey, result);
228
- } else {
229
- result[camelCaseKey] = obj[key];
230
- }
231
- }
232
- }
233
- //remove 'Default' from keys
234
- for (const key in result) {
235
- if (key.includes('Main')) {
236
- const newKey = key.replace('Main', '');
237
- result[newKey] = result[key];
238
- delete result[key];
239
- }
240
- }
241
-
242
- return result;
243
- }
244
-
245
-
246
- function hexToRGBA(hex,opacity){
247
- var c;
248
- if(/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)){
249
- c= hex.substring(1).split('');
250
- if(c.length== 3){
251
- c= [c[0], c[0], c[1], c[1], c[2], c[2]];
252
- }
253
- c= '0x'+c.join('');
254
- return 'rgba(' + [(c >> 16) & 255, (c >> 8) & 255, c & 255].join(',') + ',' + opacity + ')';
255
- }
256
- throw new Error('Bad Hex');
257
- }
258
-
259
- export function createRGBA(color:string, opacity:number) {
260
- if(!color) return
261
- else if (color.startsWith("rgba")) {
262
- //add opacity to existing rgba color
263
- const rgb = color.match(/[\d.]+/g);
264
- return `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, ${Number(rgb[3]) * opacity})`;
265
- }
266
- else if (color.startsWith("rgb")) {
267
- const rgb = color.match(/\d+/g);
268
- return `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, ${opacity})`;
269
- }
270
- else if (color.startsWith("#")) {
271
- return hexToRGBA(color, opacity);
272
- }
273
- else if (csscolors[color]) {
274
- return hexToRGBA(csscolors[color], opacity);
275
- }
276
- else {
277
- return color;
278
- }
279
- }
280
-
281
- export function parseColorForAliases(str){
282
- const aliasRegex = /alias:([^ ]+)/;
283
- const opacityRegex = /opacity:([0-9.]+)/;
284
- const darkenRegex = /darken/;
285
- const lightenRegex = /lighten/;
286
- const inverseRegex = /inverse/;
287
-
288
- // Extract alias and properties
289
- const aliasMatch = str.match(aliasRegex);
290
- const opacityMatch = str.match(opacityRegex)
291
- const darkenMatch = str.match(darkenRegex)
292
- const lightenMatch = str.match(lightenRegex)
293
- const inverseMatch = str.match(inverseRegex)
294
- return {aliasMatch,opacityMatch,darkenMatch,lightenMatch, inverseMatch}
295
- }
296
-
297
- export function darkenRGBA(rgba) {
298
- let amount = 0.2
299
- // Extract the RGBA components
300
- let [r, g, b, a] = rgba.match(/\d+/g).map(Number);
301
-
302
- // Ensure amount is between 0 and 1
303
- amount = Math.max(0, Math.min(1, amount));
304
-
305
- // Calculate the new RGB values
306
- r = Math.max(0, r * (1 - amount));
307
- g = Math.max(0, g * (1 - amount));
308
- b = Math.max(0, b * (1 - amount));
309
-
310
- // Return the new RGBA color
311
- return `rgba(${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)}, ${a})`;
312
- }
313
-
314
- export function lightenRGBA(rgba) {
315
- let amount = 0.2
316
- // Extract the RGBA components
317
- let [r, g, b, a] = rgba.match(/\d+/g).map(Number);
318
-
319
- // Ensure amount is between 0 and 1
320
- amount = Math.max(0, Math.min(1, amount));
321
-
322
- // Calculate the new RGB values
323
- r = Math.min(255, r * (1 + amount));
324
- g = Math.min(255, g * (1 + amount));
325
- b = Math.min(255, b * (1 + amount));
326
-
327
- // Return the new RGBA color
328
- return `rgba(${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)}, ${a})`;
329
- }
330
-
331
-
332
- export function inverseRGBA(rgba) {
333
- // return white or black depending on the brightness of the color
334
- let [r, g, b] = rgba.match(/\d+/g).map(Number);
335
- let brightness = (r * 299 + g * 587 + b * 114) / 1000;
336
- return brightness > 128 ? 'rgba(0,0,0,1)' : 'rgba(255,255,255,1)';
337
- }
338
-
339
-
340
- export function suggestIfTypo(names: string[], name: string): string {
341
- if (!name) {
342
- return null;
343
- }
344
- const options = {
345
- includeScore: true, // Includes score in the results to see how close matches are
346
- threshold: 0.3, // Defines the fuzziness (lower values mean stricter matches)
347
- };
348
-
349
- const fuse = new Fuse(names.filter(
350
- (n) => !!n
351
- ), options);
352
- // Search for a resource
353
- const result = fuse.search(name);
354
- if (result.length > 0) {
355
- return result[0].item;
356
- }
357
- }
358
-
359
-
360
- export function getClinetIp(headers: object) {
361
- console.log('headers', headers);
362
- return headers['CF-Connecting-IP'] ||
363
- headers['x-forwarded-for'] ||
364
- headers['x-real-ip'] ||
365
- headers['x-client-ip'] ||
366
- headers['x-proxy-user'] ||
367
- headers['x-cluster-client-ip'] ||
368
- headers['forwarded'] ||
369
- headers['remote-addr'] ||
370
- headers['client-ip'] ||
371
- headers['x-client-ip'] ||
372
- headers['x-real-ip'] || 'unknown';
373
- }
374
-
375
-
376
- export class RateLimiter {
377
- static counterData = {};
378
-
379
-
380
-
381
-
382
- /**
383
- * Very dirty version of ratelimiter for demo purposes (should not be considered as production ready)
384
- * Will be used as RateLimiter.checkRateLimit('key', '5/24h', clientIp)
385
- * Stores counter in this class, in RAM, resets limits on app restart.
386
- * Also it creates setTimeout for every call, so is not optimal for high load.
387
- * @param key - key to store rate limit for
388
- * @param limit - limit in format '5/24h' - 5 requests per 24 hours
389
- * @param clientIp
390
- */
391
- static checkRateLimit(key: string, limit: string, clientIp: string) {
392
-
393
- if (!limit) {
394
- throw new Error('Rate limit is not set');
395
- }
396
-
397
- if (!key) {
398
- throw new Error('Rate limit key is not set');
399
- }
400
-
401
- if (!clientIp) {
402
- throw new Error('Client IP is not set');
403
- }
404
-
405
- if (!limit.includes('/')) {
406
- throw new Error('Rate limit should be in format count/period, like 5/24h');
407
- }
408
-
409
- // parse limit
410
- const [count, period] = limit.split('/');
411
- const [preiodAmount, periodType] = /(\d+)(\w+)/.exec(period).slice(1);
412
- const preiodAmountNumber = parseInt(preiodAmount);
413
-
414
- // get current time
415
- const whenClear = new Date();
416
- if (periodType === 'h') {
417
- whenClear.setHours(whenClear.getHours() + preiodAmountNumber);
418
- } else if (periodType === 'd') {
419
- whenClear.setDate(whenClear.getDate() + preiodAmountNumber);
420
- } else if (periodType === 'm') {
421
- whenClear.setMinutes(whenClear.getMinutes() + preiodAmountNumber);
422
- } else if (periodType === 'y') {
423
- whenClear.setFullYear(whenClear.getFullYear() + preiodAmountNumber);
424
- } else if (periodType === 's') {
425
- whenClear.setSeconds(whenClear.getSeconds() + preiodAmountNumber);
426
- } else {
427
- throw new Error(`Unsupported period type for rate limiting: ${periodType}`);
428
- }
429
-
430
-
431
- // get current counter
432
- const counter = this.counterData[key] && this.counterData[key][clientIp] || 0;
433
- if (counter >= count) {
434
- return { error: true };
435
- }
436
- RateLimiter.incrementCounter(key, clientIp);
437
- setTimeout(() => {
438
- RateLimiter.decrementCounter(key, clientIp);
439
- }, whenClear.getTime() - Date.now());
440
-
441
-
442
- return { error: false };
443
-
444
- }
445
-
446
- static incrementCounter(key: string, ip: string) {
447
- if (!RateLimiter.counterData[key]) {
448
- RateLimiter.counterData[key] = {};
449
- }
450
- if (!RateLimiter.counterData[key][ip]) {
451
- RateLimiter.counterData[key][ip] = 0;
452
- }
453
- RateLimiter.counterData[key][ip]++;
454
- console.log('🔄️🔄️🔄️🔄️🔄️🔄️ incremented', key, ip, this.counterData[key][ip]);
455
- }
456
-
457
- static decrementCounter(key: string, ip: string) {
458
- if (!RateLimiter.counterData[key]) {
459
- RateLimiter.counterData[key] = {};
460
- }
461
- if (!RateLimiter.counterData[key][ip]) {
462
- RateLimiter.counterData[key][ip] = 0;
463
- }
464
- if (RateLimiter.counterData[key][ip] > 0) {
465
- RateLimiter.counterData[key][ip]--;
466
- }
467
- console.log('🔄️🔄️🔄️🔄️🔄️🔄️ decremented', key, ip, this.counterData[key][ip]);
468
-
469
- }
470
-
471
-
472
- }