firstly 0.0.16-next.2 → 0.1.0-next.3

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 (105) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/esm/FF_Entity.d.ts +1 -1
  3. package/esm/FF_Entity.js +9 -9
  4. package/esm/ROUTES.d.ts +1 -1
  5. package/esm/ROUTES.js +2 -2
  6. package/esm/SqlDatabase/FF_LogToConsole.d.ts +14 -0
  7. package/esm/SqlDatabase/FF_LogToConsole.js +24 -5
  8. package/esm/auth/Entities.d.ts +2 -1
  9. package/esm/auth/Entities.js +18 -14
  10. package/esm/auth/server/AuthController.server.js +86 -93
  11. package/esm/auth/server/handleAuth.d.ts +4 -2
  12. package/esm/auth/server/handleAuth.js +8 -4
  13. package/esm/auth/server/helperRole.d.ts +11 -4
  14. package/esm/auth/server/helperRole.js +29 -20
  15. package/esm/auth/server/index.d.ts +1 -0
  16. package/esm/auth/server/index.js +1 -0
  17. package/esm/auth/server/module.d.ts +27 -5
  18. package/esm/auth/server/module.js +24 -10
  19. package/esm/auth/server/providers/github.js +13 -2
  20. package/esm/auth/static/assets/Page-BHW08QWz.css +1 -0
  21. package/esm/auth/static/assets/{Page-BorYIfy9.d.ts → Page-CTZPxniP.d.ts} +2 -2
  22. package/esm/auth/static/assets/Page-CTZPxniP.js +1 -0
  23. package/esm/auth/static/assets/{Page-CqsLm8yQ.d.ts → Page-D0d9iZO-.d.ts} +2 -2
  24. package/esm/auth/static/assets/{Page-CqsLm8yQ.js → Page-D0d9iZO-.js} +1 -1
  25. package/esm/auth/static/assets/{Page-Cm4MsdIa.d.ts → Page-DXshwJi7.d.ts} +2 -2
  26. package/esm/auth/static/assets/Page-DXshwJi7.js +20 -0
  27. package/esm/auth/static/assets/{index-Borxa2ns.d.ts → index-LRDptjak.d.ts} +3 -20
  28. package/esm/auth/static/assets/{index-Borxa2ns.js → index-LRDptjak.js} +2 -2
  29. package/esm/auth/static/index.html +1 -1
  30. package/esm/auth/types.d.ts +1 -0
  31. package/esm/bin/cmd.js +16 -16
  32. package/esm/changeLog/changeLogEntities.d.ts +21 -0
  33. package/esm/changeLog/changeLogEntities.js +57 -0
  34. package/esm/changeLog/index.d.ts +3 -15
  35. package/esm/changeLog/index.js +3 -51
  36. package/esm/changeLog/server/index.d.ts +39 -28
  37. package/esm/changeLog/server/index.js +40 -29
  38. package/esm/cron/Cron.d.ts +11 -0
  39. package/esm/cron/Cron.js +43 -0
  40. package/esm/cron/Role_Cron.d.ts +3 -0
  41. package/esm/cron/Role_Cron.js +3 -0
  42. package/esm/cron/index.d.ts +3 -0
  43. package/esm/cron/index.js +3 -0
  44. package/esm/cron/server/index.d.ts +29 -11
  45. package/esm/cron/server/index.js +29 -13
  46. package/esm/feedback/FeedbackController.d.ts +3 -1
  47. package/esm/feedback/FeedbackController.js +23 -1
  48. package/esm/feedback/server/index.d.ts +2 -2
  49. package/esm/feedback/server/index.js +2 -2
  50. package/esm/feedback/types.d.ts +6 -0
  51. package/esm/feedback/ui/DialogIssue.svelte +8 -1
  52. package/esm/feedback/ui/DialogIssues.svelte +1 -1
  53. package/esm/formats/index.d.ts +1 -1
  54. package/esm/formats/index.js +1 -1
  55. package/esm/formats/strings.d.ts +2 -0
  56. package/esm/formats/strings.js +22 -0
  57. package/esm/index.d.ts +1 -2
  58. package/esm/index.js +0 -2
  59. package/esm/mail/Mail.d.ts +13 -0
  60. package/esm/mail/Mail.js +51 -0
  61. package/esm/mail/Role_Mail.d.ts +3 -0
  62. package/esm/mail/Role_Mail.js +3 -0
  63. package/esm/mail/index.d.ts +7 -2
  64. package/esm/mail/index.js +7 -2
  65. package/esm/mail/server/formatMailHelper.d.ts +16 -0
  66. package/esm/mail/server/formatMailHelper.js +113 -0
  67. package/esm/mail/server/index.d.ts +32 -19
  68. package/esm/mail/server/index.js +113 -38
  69. package/esm/server/index.d.ts +9 -6
  70. package/esm/server/index.js +28 -50
  71. package/esm/svelte/FF_Layout.svelte +2 -2
  72. package/esm/svelte/dialog/DialogManagement.svelte +2 -2
  73. package/esm/svelte/helpers.d.ts +1 -0
  74. package/esm/svelte/index.d.ts +1 -0
  75. package/esm/svelte/index.js +1 -0
  76. package/esm/svelte/initRemultSvelteReactivity.d.ts +1 -0
  77. package/esm/svelte/initRemultSvelteReactivity.js +29 -0
  78. package/esm/sveltekit/server/index.d.ts +2 -2
  79. package/esm/sveltekit/server/index.js +2 -2
  80. package/esm/ui/Button.svelte +1 -1
  81. package/esm/ui/Field.svelte +5 -3
  82. package/esm/ui/Field.svelte.d.ts +4 -1
  83. package/esm/ui/FieldGroup.svelte +2 -1
  84. package/esm/ui/FieldGroup.svelte.d.ts +4 -1
  85. package/esm/ui/GridPaginate.svelte +2 -2
  86. package/esm/ui/GridPaginate2.svelte +1 -1
  87. package/esm/ui/Loading.svelte +1 -1
  88. package/esm/ui/Tooltip.svelte +1 -1
  89. package/esm/ui/dialog/DialogForm.svelte +3 -3
  90. package/esm/ui/dialog/DialogManagement.svelte +2 -2
  91. package/esm/ui/dialog/DialogPrimitive.svelte +2 -2
  92. package/esm/ui/dialog/FormEditAction.svelte +2 -2
  93. package/esm/ui/internals/FieldContainer.svelte +2 -2
  94. package/esm/ui/internals/Textarea.svelte +2 -2
  95. package/esm/ui/internals/select/MultiSelectMelt.svelte +6 -6
  96. package/esm/ui/internals/select/SelectMelt.svelte +28 -14
  97. package/esm/ui/internals/select/SelectMelt.svelte.d.ts +4 -1
  98. package/esm/ui/link/LinkPlus.svelte +2 -2
  99. package/esm/vite/index.js +50 -52
  100. package/package.json +15 -12
  101. package/esm/auth/static/assets/Page-BorYIfy9.js +0 -1
  102. package/esm/auth/static/assets/Page-Cm4MsdIa.js +0 -20
  103. package/esm/auth/static/assets/Page-JfNiCSIG.css +0 -1
  104. package/esm/mail/templates/DefaultMail.svelte +0 -86
  105. package/esm/mail/templates/DefaultMail.svelte.d.ts +0 -30
@@ -1,5 +1,5 @@
1
1
  import { CronJob } from 'cron';
2
- import { Module } from '../../server';
2
+ import { Module } from 'remult/server';
3
3
  export declare const jobs: Record<string, {
4
4
  job: CronJob<null, unknown> | null;
5
5
  concurrentInProgress: number;
@@ -29,18 +29,43 @@ export declare const cronTime: {
29
29
  */
30
30
  every_friday_morning: string;
31
31
  };
32
+ /**
33
+ * Type for onTick function that must return a Record<string, any>
34
+ */
35
+ export type CronOnTick = () => Record<string, any> | Promise<Record<string, any>>;
36
+ /**
37
+ * Type for cron job parameters with enforced onTick return type
38
+ */
39
+ export type CronJobParams = {
40
+ cronTime: string | Date;
41
+ onTick: CronOnTick;
42
+ topic: string;
43
+ concurrent?: number;
44
+ logs?: {
45
+ starting?: boolean;
46
+ ended?: boolean;
47
+ };
48
+ start?: boolean;
49
+ runOnInit?: boolean;
50
+ timeZone?: string;
51
+ utcOffset?: string | number;
52
+ onComplete?: () => void;
53
+ };
32
54
  /**
33
55
  * usage:
34
56
  *
35
57
  * ```ts
36
- * import { cron, cronTime } from 'firstly/cron'
58
+ * import { cron, cronTime } from '..'
37
59
  *
38
60
  * export const api = firstly({
39
61
  * modules: [
40
62
  * cron([{
41
63
  * topic: 'first_cron',
42
64
  * cronTime: cronTime.every_second,
43
- * onTick: () => { console.log('hello') },
65
+ * onTick: () => {
66
+ * console.log('hello')
67
+ * return { status: 'success' }
68
+ * },
44
69
  * start: !dev, // Start in production
45
70
  * // runOnInit: dev, // nice in dev environement
46
71
  * }])
@@ -50,11 +75,4 @@ export declare const cronTime: {
50
75
  *
51
76
  * using [cron](https://www.npmjs.com/package/cron) library under the hood
52
77
  */
53
- export declare const cron: (jobsInfos: (Parameters<typeof CronJob.from>[0] & {
54
- topic: string;
55
- concurrent?: number;
56
- logs?: {
57
- starting?: boolean;
58
- ended?: boolean;
59
- };
60
- })[]) => Module;
78
+ export declare const cron: (jobsInfos: CronJobParams[]) => Module<unknown>;
@@ -1,6 +1,9 @@
1
1
  import { CronJob } from 'cron';
2
+ import { repo } from 'remult';
3
+ import { Module } from 'remult/server';
2
4
  import { green, magenta, red, yellow } from '@kitql/helpers';
3
- import { Module } from '../../server';
5
+ import { log } from '..';
6
+ import { Cron } from '../Cron';
4
7
  export const jobs = {};
5
8
  /**
6
9
  * Link to a nice Cheatsheet TODO
@@ -31,14 +34,17 @@ export const cronTime = {
31
34
  * usage:
32
35
  *
33
36
  * ```ts
34
- * import { cron, cronTime } from 'firstly/cron'
37
+ * import { cron, cronTime } from '..'
35
38
  *
36
39
  * export const api = firstly({
37
40
  * modules: [
38
41
  * cron([{
39
42
  * topic: 'first_cron',
40
43
  * cronTime: cronTime.every_second,
41
- * onTick: () => { console.log('hello') },
44
+ * onTick: () => {
45
+ * console.log('hello')
46
+ * return { status: 'success' }
47
+ * },
42
48
  * start: !dev, // Start in production
43
49
  * // runOnInit: dev, // nice in dev environement
44
50
  * }])
@@ -50,7 +56,8 @@ export const cronTime = {
50
56
  */
51
57
  export const cron = (jobsInfos) => {
52
58
  const m = new Module({
53
- name: 'cron',
59
+ key: 'cron',
60
+ entities: [Cron],
54
61
  });
55
62
  const logJobs = (topic, job, message, with_metadata = true, isSuccess = true) => {
56
63
  const l = [];
@@ -61,36 +68,45 @@ export const cron = (jobsInfos) => {
61
68
  l.push(`(${job.isActive ? green('running') : red('stopped')}, next at ${yellow(job.nextDate().toISO())})`);
62
69
  }
63
70
  if (isSuccess) {
64
- m.log.success(l.join(' '));
71
+ log.success(l.join(' '));
65
72
  }
66
73
  else {
67
- m.log.info(l.join(' '));
74
+ log.info(l.join(' '));
68
75
  }
69
76
  };
70
77
  m.initApi = async () => {
71
78
  jobsInfos.forEach((infos) => {
72
- const { topic, runOnInit, logs, concurrent, ...params } = infos;
79
+ const { topic, runOnInit, logs, concurrent, onTick: originalOnTick, ...params } = infos;
73
80
  const concurrentToUse = concurrent ?? 1;
74
- const onTickSaved = params.onTick;
75
- const fullOnTick = async () => {
81
+ // Create a wrapper that converts the return type to void for CronJob
82
+ const wrappedOnTick = async () => {
76
83
  if (jobs[topic].concurrentInProgress < concurrentToUse) {
77
84
  jobs[topic].concurrentInProgress = jobs[topic].concurrentInProgress + 1;
85
+ const rCron = await repo(Cron).insert({ topic });
78
86
  if (logs?.starting === undefined || logs?.starting === true) {
79
87
  logJobs(topic, job, 'starting...', false, false);
80
88
  }
81
- // @ts-ignore
82
- await onTickSaved();
89
+ const res = await originalOnTick();
90
+ log.info(`[${topic}] result:`, res);
91
+ rCron.result = res;
92
+ rCron.endedAt = new Date();
93
+ rCron.status = 'ended';
94
+ await repo(Cron).save(rCron);
83
95
  if (logs?.ended === undefined || logs?.ended === true) {
84
96
  logJobs(topic, job, 'done');
85
97
  }
86
98
  jobs[topic].concurrentInProgress = jobs[topic].concurrentInProgress - 1;
87
99
  }
88
100
  else {
101
+ const rCron = await repo(Cron).insert({ topic, status: 'skipped' });
89
102
  logJobs(topic, job, `skipped because of concurrent limit (${yellow(concurrentToUse.toString())})`, false, false);
90
103
  }
91
104
  };
92
- params.onTick = fullOnTick;
93
- const job = CronJob.from(params);
105
+ // Use type assertion to bypass complex generic type issues
106
+ const job = CronJob.from({
107
+ ...params,
108
+ onTick: wrappedOnTick,
109
+ });
94
110
  jobs[topic] = { job, concurrentInProgress: 0 };
95
111
  logJobs(topic, job, 'setup done');
96
112
  // If not it will be done too early
@@ -19,15 +19,17 @@ export declare class FeedbackController {
19
19
  who?: string;
20
20
  createdAt: Date;
21
21
  public: boolean;
22
+ title: string;
22
23
  }[];
23
24
  labels: any;
24
25
  highlight: any;
26
+ title: any;
25
27
  }>;
26
28
  static createIssue(milestoneId: string, title: string, body: string, page: string): Promise<{
27
29
  id: string;
28
30
  number: number;
29
31
  }>;
30
- static addCommentOnIssue(issueId: string, body: string, page: string, labels: {
32
+ static addCommentOnIssue(issueId: string, issueNumber: number, title: string, body: string, page: string, labels: {
31
33
  id: string;
32
34
  name: string;
33
35
  }[]): Promise<string>;
@@ -162,6 +162,7 @@ export class FeedbackController {
162
162
  createdAt
163
163
  bodyHTML
164
164
  state
165
+ title
165
166
  labels(first: 25){
166
167
  nodes{
167
168
  id
@@ -196,6 +197,7 @@ export class FeedbackController {
196
197
  bodyHTML: data.repository.issue.bodyHTML,
197
198
  createdAt: data.repository.issue.createdAt,
198
199
  public: true,
200
+ title: data.repository.issue.title,
199
201
  };
200
202
  items.push(firstItem);
201
203
  const comments = data.repository.issue.comments.nodes;
@@ -211,6 +213,7 @@ export class FeedbackController {
211
213
  bodyHTML: comments[i].bodyHTML,
212
214
  createdAt: new Date(comments[i].createdAt),
213
215
  public: nbEye && nbEye > 0 ? true : false,
216
+ title: data.repository.issue.title,
214
217
  });
215
218
  }
216
219
  }
@@ -223,6 +226,7 @@ export class FeedbackController {
223
226
  items: items.filter((c) => c.public),
224
227
  labels: data.repository.issue.labels.nodes,
225
228
  highlight: hasWaitingForAnswerLabel,
229
+ title: data.repository.issue.title,
226
230
  };
227
231
  return toRet;
228
232
  }
@@ -265,9 +269,18 @@ export class FeedbackController {
265
269
  });
266
270
  const toRet = newIssue.createIssue.issue;
267
271
  await addMetaData(toRet.id, remult.user?.name, page);
272
+ remult.context.feedbackOptions.saved?.({
273
+ number: toRet.number,
274
+ title: title,
275
+ body,
276
+ metadata: {
277
+ author: JSON.stringify(remult.user?.name),
278
+ page,
279
+ },
280
+ });
268
281
  return toRet;
269
282
  }
270
- static async addCommentOnIssue(issueId, body, page, labels) {
283
+ static async addCommentOnIssue(issueId, issueNumber, title, body, page, labels) {
271
284
  const inputComment = {
272
285
  subjectId: issueId,
273
286
  body,
@@ -297,6 +310,15 @@ export class FeedbackController {
297
310
  inputIssue,
298
311
  });
299
312
  await addMetaData(issueId, remult.user?.name, page);
313
+ remult.context.feedbackOptions.saved?.({
314
+ number: issueNumber,
315
+ title,
316
+ body,
317
+ metadata: {
318
+ author: JSON.stringify(remult.user?.name),
319
+ page,
320
+ },
321
+ });
300
322
  return 'done';
301
323
  }
302
324
  static async close(issueId, labels) {
@@ -1,6 +1,6 @@
1
- import { Module } from '../../server';
1
+ import { ModuleFF } from '../../server';
2
2
  import type { FeedbackOptions } from '../types';
3
- export declare const feedback: (o: FeedbackOptions) => Module;
3
+ export declare const feedback: (o: FeedbackOptions) => ModuleFF;
4
4
  declare module 'remult' {
5
5
  interface RemultContext {
6
6
  feedbackOptions: FeedbackOptions;
@@ -1,8 +1,8 @@
1
1
  import { remult } from 'remult';
2
- import { Module } from '../../server';
2
+ import { ModuleFF } from '../../server';
3
3
  import { FeedbackController } from '../FeedbackController';
4
4
  export const feedback = (o) => {
5
- return new Module({
5
+ return new ModuleFF({
6
6
  name: 'feedback',
7
7
  controllers: [FeedbackController],
8
8
  initRequest: async (kitEvent, op) => {
@@ -10,5 +10,11 @@ export type FeedbackOptions = {
10
10
  };
11
11
  highlight_label?: string;
12
12
  create_label?: string;
13
+ saved?: (args: {
14
+ number: number;
15
+ title: string;
16
+ body: string;
17
+ metadata: Record<string, any>;
18
+ }) => Promise<void>;
13
19
  };
14
20
  export declare const FEEDBACK_OPTIONS: FeedbackOptions;
@@ -41,7 +41,14 @@
41
41
  const result = await FeedbackController.createIssue(milestoneId, title, content, p)
42
42
  issueNumber = result.number
43
43
  } else {
44
- await FeedbackController.addCommentOnIssue(issue.id, content, p, issue.labels)
44
+ await FeedbackController.addCommentOnIssue(
45
+ issue.id,
46
+ issueNumber!,
47
+ issue.title,
48
+ content,
49
+ p,
50
+ issue.labels,
51
+ )
45
52
  }
46
53
 
47
54
  content = ''
@@ -86,7 +86,7 @@
86
86
  >
87
87
  <div class="flex w-full justify-center justify-items-center text-left">
88
88
  <div class="flex-grow">
89
- <span class="text-base-content/60 mr-2 inline-block w-8 text-right text-xs italic"
89
+ <span class="mr-2 inline-block w-8 text-right text-xs italic text-base-content/60"
90
90
  >#{issue.number}</span
91
91
  >
92
92
  {@html issue.titleHTML}
@@ -1,4 +1,4 @@
1
1
  export { displayCurrency, displayCurrencyK, displayPercent, displayCurrencyWOSuffix, } from './numbers.js';
2
- export { formatNumber, extractMailInfo } from './strings.js';
2
+ export { formatNumber, extractMailInfo, slugify, nameify, displayPhone, suffixWithS, arrToStr, mask, toTitleCase, } from './strings.js';
3
3
  export { offsetedToPlainDate, plainDateCompare, isBetween, dateISOToPlainDate } from './dates.js';
4
4
  export type { KitPlainDateRange } from './dates.js';
@@ -1,3 +1,3 @@
1
1
  export { displayCurrency, displayCurrencyK, displayPercent, displayCurrencyWOSuffix, } from './numbers.js';
2
- export { formatNumber, extractMailInfo } from './strings.js';
2
+ export { formatNumber, extractMailInfo, slugify, nameify, displayPhone, suffixWithS, arrToStr, mask, toTitleCase, } from './strings.js';
3
3
  export { offsetedToPlainDate, plainDateCompare, isBetween, dateISOToPlainDate } from './dates.js';
@@ -9,3 +9,5 @@ export declare const extractMailInfo: (mail: string, withThrow?: boolean) => {
9
9
  lastName: string;
10
10
  email: string;
11
11
  };
12
+ export declare function slugify(str: string | undefined): string | undefined;
13
+ export declare function nameify(str: string | undefined): string | undefined;
@@ -96,3 +96,25 @@ export const extractMailInfo = (mail, withThrow = true) => {
96
96
  email: '',
97
97
  };
98
98
  };
99
+ export function slugify(str) {
100
+ if (str === undefined)
101
+ return undefined;
102
+ return str
103
+ .toLowerCase()
104
+ .trim()
105
+ .replace(/[^\w.-]+/g, '-')
106
+ .replace(/[\s_-]+/g, '-')
107
+ .replace(/^-+|-+$/g, '');
108
+ }
109
+ export function nameify(str) {
110
+ if (str === undefined)
111
+ return undefined;
112
+ return str
113
+ .toLowerCase()
114
+ .trim()
115
+ .replace(/\./g, ' ')
116
+ .replace(/\s+/g, ' ')
117
+ .replace(/(?:^|\s|-)\S/g, (match) => match.toUpperCase())
118
+ .trim()
119
+ .split('@')[0];
120
+ }
package/esm/index.d.ts CHANGED
@@ -44,8 +44,6 @@ export { getEntityDisplayValue, isError, getFieldLinkDisplayValue, getEnum, getE
44
44
  export { buildWhere, getPlaceholder, buildSearchWhere, cellsBuildor, cellBuildor, fieldsOf, containsWords, } from './cellsBuildor.js';
45
45
  export { storeItem };
46
46
  export { storeList };
47
- export { displayPhone, arrToStr } from './formats/strings.js';
48
- export { displayCurrency } from './formats/numbers.js';
49
47
  export { tw } from './utils/tailwind.js';
50
48
  export { FilterEntity } from './virtual/FilterEntity.js';
51
49
  export { UIEntity } from './virtual/UIEntity.js';
@@ -68,6 +66,7 @@ declare module 'remult' {
68
66
  onSuccess: (entity: entityType, newItem: any) => Promise<void>;
69
67
  onError?: () => void;
70
68
  };
69
+ default_select_if_one_item?: boolean;
71
70
  multiSelect?: boolean;
72
71
  skipForDefaultField?: boolean;
73
72
  }
package/esm/index.js CHANGED
@@ -35,8 +35,6 @@ export { getEntityDisplayValue, isError, getFieldLinkDisplayValue, getEnum, getE
35
35
  export { buildWhere, getPlaceholder, buildSearchWhere, cellsBuildor, cellBuildor, fieldsOf, containsWords, } from './cellsBuildor.js';
36
36
  export { storeItem };
37
37
  export { storeList };
38
- export { displayPhone, arrToStr } from './formats/strings.js';
39
- export { displayCurrency } from './formats/numbers.js';
40
38
  export { tw } from './utils/tailwind.js';
41
39
  // Hummm... I don't know if we should keep it...
42
40
  export { FilterEntity } from './virtual/FilterEntity.js';
@@ -0,0 +1,13 @@
1
+ declare const statuses: readonly ["transport_not_configured", "sent", "error"];
2
+ type StatusType = (typeof statuses)[number];
3
+ export declare class Mail {
4
+ id?: string;
5
+ createdAt: Date;
6
+ topic: string;
7
+ to: string;
8
+ metadata: Record<string, any>;
9
+ html: string;
10
+ status: StatusType;
11
+ errorInfo: string;
12
+ }
13
+ export {};
@@ -0,0 +1,51 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { Entity, Fields } from 'remult';
8
+ import { Role_Mail } from './Role_Mail';
9
+ const statuses = ['transport_not_configured', 'sent', 'error'];
10
+ let Mail = class Mail {
11
+ id;
12
+ createdAt = new Date();
13
+ topic;
14
+ to;
15
+ metadata = {};
16
+ html = '';
17
+ status = 'sent';
18
+ errorInfo = '';
19
+ };
20
+ __decorate([
21
+ Fields.cuid()
22
+ ], Mail.prototype, "id", void 0);
23
+ __decorate([
24
+ Fields.createdAt()
25
+ ], Mail.prototype, "createdAt", void 0);
26
+ __decorate([
27
+ Fields.string({ required: true })
28
+ ], Mail.prototype, "topic", void 0);
29
+ __decorate([
30
+ Fields.string({ required: true })
31
+ ], Mail.prototype, "to", void 0);
32
+ __decorate([
33
+ Fields.json()
34
+ ], Mail.prototype, "metadata", void 0);
35
+ __decorate([
36
+ Fields.string()
37
+ ], Mail.prototype, "html", void 0);
38
+ __decorate([
39
+ Fields.literal(() => statuses)
40
+ ], Mail.prototype, "status", void 0);
41
+ __decorate([
42
+ Fields.string()
43
+ ], Mail.prototype, "errorInfo", void 0);
44
+ Mail = __decorate([
45
+ Entity('_ff_mails', {
46
+ caption: 'Mails',
47
+ allowApiCrud: Role_Mail.Mail_Admin,
48
+ defaultOrderBy: { createdAt: 'desc' },
49
+ })
50
+ ], Mail);
51
+ export { Mail };
@@ -0,0 +1,3 @@
1
+ export declare const Role_Mail: {
2
+ readonly Mail_Admin: "mail.admin";
3
+ };
@@ -0,0 +1,3 @@
1
+ export const Role_Mail = {
2
+ Mail_Admin: 'mail.admin',
3
+ };
@@ -1,2 +1,7 @@
1
- import { default as DefaultMail } from './templates/DefaultMail.svelte';
2
- export { DefaultMail };
1
+ import { Log } from '@kitql/helpers';
2
+ import { Mail } from './Mail';
3
+ export declare const key = "mail";
4
+ export declare const log: Log;
5
+ export declare const mailEntities: {
6
+ Mail: typeof Mail;
7
+ };
package/esm/mail/index.js CHANGED
@@ -1,2 +1,7 @@
1
- import { default as DefaultMail } from './templates/DefaultMail.svelte';
2
- export { DefaultMail };
1
+ import { Log } from '@kitql/helpers';
2
+ import { Mail } from './Mail';
3
+ export const key = 'mail';
4
+ export const log = new Log(key);
5
+ export const mailEntities = {
6
+ Mail,
7
+ };
@@ -0,0 +1,16 @@
1
+ export type MailStyle = {
2
+ service: string;
3
+ primaryColor: string;
4
+ secondaryColor: string;
5
+ subject: string;
6
+ title: string;
7
+ sections: {
8
+ html: string;
9
+ cta?: {
10
+ html: string;
11
+ link: string;
12
+ } | undefined;
13
+ }[];
14
+ footer: string;
15
+ };
16
+ export declare const toHtml: (args: MailStyle) => string;
@@ -0,0 +1,113 @@
1
+ export const toHtml = (args) => {
2
+ const { service, primaryColor, secondaryColor, title, footer, sections } = args;
3
+ return `<body style="background-color: #f4f4f4; margin: 0 !important; padding: 0 !important; color: black">
4
+ <table border="0" cellpadding="0" cellspacing="0" width="100%">
5
+ <tr>
6
+ <td bgcolor="${primaryColor}" align="center">
7
+ <table border="0" cellpadding="0" cellspacing="0" width="480">
8
+ <tr>
9
+ <td align="center" valign="top" style="padding: 30px 10px 30px 10px;">
10
+ <div
11
+ style="display: block; font-family: Helvetica, Arial, sans-serif; color: #ffffff; font-size: 18px;"
12
+ border="0"
13
+ >
14
+ ${service}
15
+ </div>
16
+ </td>
17
+ </tr>
18
+ </table>
19
+ </td>
20
+ </tr>
21
+ <tr>
22
+ <td bgcolor="${primaryColor}" align="center" style="padding: 0px 35px 0px 35px;">
23
+ <table border="0" cellpadding="0" cellspacing="0" width="100%">
24
+ <tr>
25
+ <td
26
+ bgcolor="#ffffff"
27
+ align="left"
28
+ valign="top"
29
+ style="padding: 30px 30px 20px 30px; border-radius: 20px 20px 0px 0px; color: #111111; font-family: Helvetica, Arial, sans-serif; font-size: 48px; font-weight: 400; line-height: 48px;"
30
+ >
31
+ <h1 style="font-size: 32px; font-weight: 400; margin: 0;">${title}</h1>
32
+ </td>
33
+ </tr>
34
+ </table>
35
+ </td>
36
+ </tr>
37
+ <tr>
38
+ <td bgcolor="#f4f4f4" align="center" style="padding: 0px 35px 0px 35px;">
39
+ <table border="0" cellpadding="0" cellspacing="0" width="100%">
40
+ ${sections.map((section, i) => sectionToHtml(i, primaryColor, secondaryColor, section))
41
+ .join(`
42
+ `)}
43
+ </table>
44
+ </td>
45
+ </tr>
46
+ <tr>
47
+ <td bgcolor="#f4f4f4" align="center" style="padding: 0px 10px 0px 10px;">
48
+ <table border="0" cellpadding="0" cellspacing="0" width="480">
49
+ <tr>
50
+ <td
51
+ bgcolor="#f4f4f4"
52
+ align="left"
53
+ style="padding: 30px 30px 30px 30px; color: #666666; font-family: Helvetica, Arial, sans-serif; font-size: 14px; font-weight: 400; line-height: 18px;"
54
+ >
55
+ <center>
56
+ ${footer}
57
+ </center>
58
+ </td>
59
+ </tr>
60
+ </table>
61
+ </td>
62
+ </tr>
63
+ </table>
64
+ </body>
65
+ `;
66
+ };
67
+ const sectionToHtml = (i, primaryColor, secondaryColor, section) => `
68
+ <tr>
69
+ <td bgcolor="#ffffff" align="left">
70
+ <table width="100%" border="0" cellspacing="0" cellpadding="0">
71
+ <tr>
72
+ <td
73
+ bgcolor="#ffffff"
74
+ align="left"
75
+ style="padding: 30px 30px 30px 30px; ${i > 0 ? `border-top:1px solid ${primaryColor};` : ''}"
76
+ >
77
+ ${section.html}
78
+ ${section.cta ? ctaToHtml(secondaryColor, section.cta.html, section.cta.link) : ''}
79
+ </td>
80
+ </tr>
81
+ </table>
82
+ </td>
83
+ </tr>
84
+ `;
85
+ const ctaToHtml = (secondaryColor, html, href) => `
86
+ <tr>
87
+ <td bgcolor="#ffffff" align="center">
88
+ <table width="100%" border="0" cellspacing="0" cellpadding="0">
89
+ <tr>
90
+ <td
91
+ bgcolor="#ffffff"
92
+ align="center"
93
+ style="padding: 0 0 30px 0;"
94
+ >
95
+ <table border="0" cellspacing="0" cellpadding="0">
96
+ <tr>
97
+ <td align="left" style="border-radius: 3px;" bgcolor="${secondaryColor}">
98
+ <!-- CTA -->
99
+ <a
100
+ href="${href}"
101
+ target="_blank"
102
+ style="font-size: 20px; font-family: Helvetica, Arial, sans-serif; text-decoration: none; color: #ffffff; text-decoration: none; padding: 11px 22px; border-radius: 2px; display: inline-block;"
103
+ >${html}</a
104
+ >
105
+ </td>
106
+ </tr>
107
+ </table>
108
+ </td>
109
+ </tr>
110
+ </table>
111
+ </td>
112
+ </tr>
113
+ `;