proteum 1.0.2 → 2.0.0
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/AGENTS.md +101 -0
- package/agents/codex/AGENTS.md +95 -0
- package/agents/codex/CODING_STYLE.md +71 -0
- package/agents/codex/agents.md.zip +0 -0
- package/agents/codex/client/AGENTS.md +102 -0
- package/agents/codex/client/pages/AGENTS.md +35 -0
- package/agents/codex/server/routes/AGENTS.md +12 -0
- package/agents/codex/server/services/AGENTS.md +137 -0
- package/agents/codex/tests/AGENTS.md +8 -0
- package/cli/app/config.ts +13 -11
- package/cli/app/index.ts +74 -82
- package/cli/bin.js +1 -1
- package/cli/commands/build.ts +51 -14
- package/cli/commands/check.ts +19 -0
- package/cli/commands/deploy/app.ts +4 -8
- package/cli/commands/deploy/web.ts +16 -20
- package/cli/commands/dev.ts +189 -64
- package/cli/commands/devEvents.ts +106 -0
- package/cli/commands/init.ts +63 -57
- package/cli/commands/lint.ts +21 -0
- package/cli/commands/refresh.ts +18 -0
- package/cli/commands/typecheck.ts +18 -0
- package/cli/compiler/client/identite.ts +80 -53
- package/cli/compiler/client/index.ts +139 -213
- package/cli/compiler/common/bundleAnalysis.ts +94 -0
- package/cli/compiler/common/clientManifest.ts +67 -0
- package/cli/compiler/common/controllers.ts +288 -0
- package/cli/compiler/common/files/autres.ts +7 -18
- package/cli/compiler/common/files/images.ts +40 -37
- package/cli/compiler/common/files/style.ts +11 -22
- package/cli/compiler/common/generatedRouteModules.ts +368 -0
- package/cli/compiler/common/index.ts +31 -65
- package/cli/compiler/common/loaders/forbid-ssr-import.js +13 -0
- package/cli/compiler/common/rspackAliases.ts +13 -0
- package/cli/compiler/common/scripts.ts +37 -0
- package/cli/compiler/index.ts +781 -230
- package/cli/compiler/server/index.ts +59 -75
- package/cli/compiler/writeIfChanged.ts +21 -0
- package/cli/index.ts +71 -72
- package/cli/paths.ts +51 -57
- package/cli/print.ts +17 -11
- package/cli/tsconfig.json +5 -4
- package/cli/utils/agents.ts +100 -0
- package/cli/utils/check.ts +71 -0
- package/cli/utils/index.ts +1 -3
- package/cli/utils/keyboard.ts +8 -25
- package/cli/utils/runProcess.ts +30 -0
- package/client/app/component.tsx +29 -29
- package/client/app/index.ts +36 -57
- package/client/app/service.ts +7 -12
- package/client/app.tsconfig.json +2 -2
- package/client/components/Dialog/Manager.ssr.tsx +40 -0
- package/client/components/Dialog/Manager.tsx +119 -150
- package/client/components/Dialog/status.tsx +3 -3
- package/client/components/index.ts +1 -1
- package/client/components/types.d.ts +1 -3
- package/client/dev/hmr.ts +65 -0
- package/client/global.d.ts +2 -2
- package/client/hooks.ts +6 -9
- package/client/index.ts +2 -1
- package/client/islands/index.ts +7 -0
- package/client/islands/useDeferredModule.ts +199 -0
- package/client/pages/_layout/index.tsx +4 -12
- package/client/pages/useHeader.tsx +14 -21
- package/client/router.ts +27 -0
- package/client/services/router/components/Link.tsx +34 -27
- package/client/services/router/components/Page.tsx +6 -14
- package/client/services/router/components/router.ssr.tsx +36 -0
- package/client/services/router/components/router.tsx +63 -83
- package/client/services/router/index.tsx +185 -220
- package/client/services/router/request/api.ts +97 -119
- package/client/services/router/request/history.ts +2 -2
- package/client/services/router/request/index.ts +13 -12
- package/client/services/router/request/multipart.ts +72 -62
- package/client/services/router/response/index.tsx +68 -61
- package/client/services/router/response/page.ts +28 -32
- package/client/utils/dom.ts +17 -33
- package/common/app/index.ts +3 -3
- package/common/data/chaines/index.ts +22 -23
- package/common/data/dates.ts +35 -70
- package/common/data/markdown.ts +42 -39
- package/common/dev/serverHotReload.ts +26 -0
- package/common/errors/index.tsx +110 -142
- package/common/router/contracts.ts +29 -0
- package/common/router/index.ts +89 -108
- package/common/router/layouts.ts +34 -47
- package/common/router/pageSetup.ts +50 -0
- package/common/router/register.ts +53 -24
- package/common/router/request/api.ts +30 -36
- package/common/router/request/index.ts +2 -8
- package/common/router/response/index.ts +8 -15
- package/common/router/response/page.ts +70 -58
- package/common/utils.ts +1 -1
- package/doc/TODO.md +1 -1
- package/eslint.js +62 -0
- package/package.json +12 -47
- package/prettier.config.cjs +9 -0
- package/scripts/cleanup-generated-controllers.ts +62 -0
- package/scripts/fix-reference-app-typing.ts +490 -0
- package/scripts/refactor-client-app-imports.ts +244 -0
- package/scripts/refactor-client-pages.ts +587 -0
- package/scripts/refactor-server-controllers.ts +470 -0
- package/scripts/refactor-server-runtime-aliases.ts +360 -0
- package/scripts/restore-client-app-import-files.ts +41 -0
- package/scripts/restore-files-from-git-head.ts +20 -0
- package/scripts/update-codex-agents.ts +35 -0
- package/server/app/commands.ts +35 -64
- package/server/app/container/config.ts +48 -59
- package/server/app/container/console/index.ts +202 -248
- package/server/app/container/index.ts +33 -71
- package/server/app/controller/index.ts +61 -0
- package/server/app/index.ts +39 -105
- package/server/app/service/container.ts +41 -42
- package/server/app/service/index.ts +120 -147
- package/server/context.ts +1 -1
- package/server/index.ts +25 -1
- package/server/services/auth/index.ts +75 -115
- package/server/services/auth/router/index.ts +31 -32
- package/server/services/auth/router/request.ts +14 -16
- package/server/services/cron/CronTask.ts +13 -26
- package/server/services/cron/index.ts +14 -36
- package/server/services/disks/driver.ts +40 -58
- package/server/services/disks/drivers/local/index.ts +79 -90
- package/server/services/disks/drivers/s3/index.ts +116 -163
- package/server/services/disks/index.ts +23 -38
- package/server/services/email/index.ts +45 -104
- package/server/services/email/utils.ts +14 -27
- package/server/services/fetch/index.ts +53 -85
- package/server/services/prisma/Facet.ts +39 -91
- package/server/services/prisma/index.ts +74 -110
- package/server/services/router/generatedRuntime.ts +29 -0
- package/server/services/router/http/index.ts +78 -73
- package/server/services/router/http/multipart.ts +19 -42
- package/server/services/router/index.ts +378 -365
- package/server/services/router/request/api.ts +26 -25
- package/server/services/router/request/index.ts +44 -51
- package/server/services/router/request/service.ts +7 -11
- package/server/services/router/request/validation/zod.ts +111 -148
- package/server/services/router/response/index.ts +110 -125
- package/server/services/router/response/mask/Filter.ts +31 -72
- package/server/services/router/response/mask/index.ts +8 -15
- package/server/services/router/response/mask/selecteurs.ts +11 -25
- package/server/services/router/response/page/clientManifest.ts +25 -0
- package/server/services/router/response/page/document.tsx +199 -127
- package/server/services/router/response/page/index.tsx +89 -94
- package/server/services/router/service.ts +13 -15
- package/server/services/schema/index.ts +17 -26
- package/server/services/schema/request.ts +19 -33
- package/server/services/schema/router/index.ts +8 -11
- package/server/services/security/encrypt/aes/index.ts +15 -35
- package/server/utils/slug.ts +29 -35
- package/skills/clean-project-code/SKILL.md +63 -0
- package/skills/clean-project-code/agents/openai.yaml +4 -0
- package/tsconfig.common.json +4 -3
- package/tsconfig.json +4 -1
- package/types/aliases.d.ts +17 -21
- package/types/controller-input.test.ts +48 -0
- package/types/express-extra.d.ts +6 -0
- package/types/global/constants.d.ts +13 -0
- package/types/global/express-extra.d.ts +6 -0
- package/types/global/modules.d.ts +13 -16
- package/types/global/utils.d.ts +17 -49
- package/types/global/vendors.d.ts +62 -0
- package/types/icons.d.ts +65 -1
- package/types/uuid.d.ts +3 -0
- package/types/vendors.d.ts +62 -0
- package/cli/compiler/common/babel/index.ts +0 -170
- package/cli/compiler/common/babel/plugins/index.ts +0 -0
- package/cli/compiler/common/babel/plugins/services.ts +0 -586
- package/cli/compiler/common/babel/routes/imports.ts +0 -127
- package/cli/compiler/common/babel/routes/routes.ts +0 -1130
- package/client/services/captcha/index.ts +0 -67
- package/client/services/socket/index.ts +0 -147
- package/common/data/rte/nodes.ts +0 -83
- package/common/data/stats.ts +0 -90
- package/common/utils/rte.ts +0 -183
- package/server/services/auth/old.ts +0 -277
- package/server/services/cache/commands.ts +0 -41
- package/server/services/cache/index.ts +0 -297
- package/server/services/cache/service.json +0 -6
- package/server/services/socket/index.ts +0 -162
- package/server/services/socket/scope.ts +0 -226
- package/server/services/socket/service.json +0 -6
- package/server/services_old/SocketClient.ts +0 -92
- package/server/services_old/Token.old.ts +0 -97
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
----------------------------------*/
|
|
4
4
|
|
|
5
5
|
// Core
|
|
6
|
-
import type { Application } from '@server/app';
|
|
6
|
+
import type { Application } from '@server/app/index';
|
|
7
7
|
import Service from '@server/app/service';
|
|
8
8
|
import markdown from '@common/data/markdown';
|
|
9
9
|
|
|
@@ -14,27 +14,18 @@ import { jsonToHtml } from './utils';
|
|
|
14
14
|
- SERVICE CONFIG
|
|
15
15
|
----------------------------------*/
|
|
16
16
|
|
|
17
|
-
const LogPrefix = `[services][email]
|
|
17
|
+
const LogPrefix = `[services][email]`;
|
|
18
18
|
|
|
19
19
|
export type Config = {
|
|
20
|
-
debug: boolean
|
|
21
|
-
simulateWhenLocal: boolean
|
|
22
|
-
default: {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
bugReport: {
|
|
26
|
-
from: TPerson,
|
|
27
|
-
to: TPerson
|
|
28
|
-
},
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export type Hooks = {
|
|
32
|
-
|
|
33
|
-
}
|
|
20
|
+
debug: boolean;
|
|
21
|
+
simulateWhenLocal: boolean;
|
|
22
|
+
default: { from: TPerson };
|
|
23
|
+
bugReport: { from: TPerson; to: TPerson };
|
|
24
|
+
};
|
|
34
25
|
|
|
35
|
-
export type
|
|
26
|
+
export type Hooks = {};
|
|
36
27
|
|
|
37
|
-
}
|
|
28
|
+
export type Services = {};
|
|
38
29
|
|
|
39
30
|
/*----------------------------------
|
|
40
31
|
- TYPES: EMAILS
|
|
@@ -42,133 +33,84 @@ export type Services = {
|
|
|
42
33
|
|
|
43
34
|
export type TEmail = THtmlEmail | TMarkdownEmail;
|
|
44
35
|
|
|
45
|
-
type TPerson = {
|
|
46
|
-
name?: string,
|
|
47
|
-
email: string
|
|
48
|
-
}
|
|
36
|
+
type TPerson = { name?: string; email: string };
|
|
49
37
|
|
|
50
|
-
type TBaseEmail = {
|
|
51
|
-
to: TPerson | TPerson[],
|
|
52
|
-
cc?: TPerson | TPerson[]
|
|
53
|
-
from?: TPerson,
|
|
54
|
-
};
|
|
38
|
+
type TBaseEmail = { to: TPerson | TPerson[]; cc?: TPerson | TPerson[]; from?: TPerson };
|
|
55
39
|
|
|
56
|
-
export type THtmlEmail = TBaseEmail & {
|
|
57
|
-
subject: string,
|
|
58
|
-
html: string | { [label: string]: any },
|
|
59
|
-
}
|
|
40
|
+
export type THtmlEmail = TBaseEmail & { subject: string; html: string | { [label: string]: any } };
|
|
60
41
|
|
|
61
|
-
export type TMarkdownEmail = TBaseEmail & {
|
|
62
|
-
subject: string,
|
|
63
|
-
markdown: string,
|
|
64
|
-
}
|
|
42
|
+
export type TMarkdownEmail = TBaseEmail & { subject: string; markdown: string };
|
|
65
43
|
|
|
66
|
-
export type TCompleteEmail = With<THtmlEmail, {
|
|
67
|
-
to: TPerson[],
|
|
68
|
-
from: TPerson,
|
|
69
|
-
cc: TPerson[]
|
|
70
|
-
}>;
|
|
44
|
+
export type TCompleteEmail = With<THtmlEmail, { to: TPerson[]; from: TPerson; cc: TPerson[] }>;
|
|
71
45
|
|
|
72
|
-
type TShortEmailSendArgs =
|
|
73
|
-
to: string,
|
|
74
|
-
subject: string,
|
|
75
|
-
markdown: string,
|
|
76
|
-
options?: TOptions
|
|
77
|
-
]
|
|
46
|
+
type TShortEmailSendArgs = [to: string, subject: string, markdown: string, options?: TOptions];
|
|
78
47
|
|
|
79
|
-
type TCompleteEmailSendArgs = [
|
|
80
|
-
emails: TEmail | TEmail[],
|
|
81
|
-
options?: TOptions
|
|
82
|
-
]
|
|
48
|
+
type TCompleteEmailSendArgs = [emails: TEmail | TEmail[], options?: TOptions];
|
|
83
49
|
|
|
84
50
|
type TEmailSendArgs = TShortEmailSendArgs | TCompleteEmailSendArgs;
|
|
85
51
|
|
|
86
52
|
/*----------------------------------
|
|
87
53
|
- TYPES: OPTIONS
|
|
88
54
|
----------------------------------*/
|
|
89
|
-
type TOptions = {
|
|
90
|
-
transporter?: string
|
|
91
|
-
}
|
|
55
|
+
type TOptions = { transporter?: string };
|
|
92
56
|
|
|
93
57
|
/*----------------------------------
|
|
94
58
|
- FONCTIONS
|
|
95
59
|
----------------------------------*/
|
|
96
|
-
export default abstract class Email<TConfig extends Config>
|
|
97
|
-
|
|
98
|
-
|
|
60
|
+
export default abstract class Email<TConfig extends Config, TApplication extends Application = Application> extends Service<
|
|
61
|
+
TConfig,
|
|
62
|
+
Hooks,
|
|
63
|
+
TApplication,
|
|
64
|
+
TApplication
|
|
65
|
+
> {
|
|
99
66
|
/*----------------------------------
|
|
100
67
|
- ACTIONS
|
|
101
68
|
----------------------------------*/
|
|
102
69
|
|
|
103
|
-
protected abstract sendNow(
|
|
104
|
-
|
|
105
|
-
public async send( to: string, subject: string, markdown: string, options?: TOptions );
|
|
106
|
-
public async send( emails: TEmail | TEmail[], options?: TOptions ): Promise<void>;
|
|
107
|
-
public async send( ...args: TEmailSendArgs ): Promise<void> {
|
|
70
|
+
protected abstract sendNow(emails: TCompleteEmail[]): Promise<void>;
|
|
108
71
|
|
|
72
|
+
public async send(to: string, subject: string, markdown: string, options?: TOptions): Promise<void>;
|
|
73
|
+
public async send(emails: TEmail | TEmail[], options?: TOptions): Promise<void>;
|
|
74
|
+
public async send(...args: TEmailSendArgs): Promise<void> {
|
|
109
75
|
let emails: TEmail[] | TEmail;
|
|
110
76
|
let options: TOptions | undefined;
|
|
111
77
|
if (typeof args[0] === 'string') {
|
|
112
78
|
const [to, subject, markdown, opts] = args as TShortEmailSendArgs;
|
|
113
|
-
emails = [{
|
|
114
|
-
to: { email: to },
|
|
115
|
-
subject,
|
|
116
|
-
markdown
|
|
117
|
-
}]
|
|
79
|
+
emails = [{ to: { email: to }, subject, markdown }];
|
|
118
80
|
options = opts;
|
|
119
81
|
} else {
|
|
120
|
-
|
|
121
|
-
(
|
|
122
|
-
if (
|
|
123
|
-
emails = [emails];
|
|
124
|
-
else if (emails.length === 0)
|
|
125
|
-
return console.warn(LogPrefix, `No email to send.`);
|
|
82
|
+
[emails, options] = args as TCompleteEmailSendArgs;
|
|
83
|
+
if (!Array.isArray(emails)) emails = [emails];
|
|
84
|
+
else if (emails.length === 0) return console.warn(LogPrefix, `No email to send.`);
|
|
126
85
|
}
|
|
127
86
|
|
|
128
|
-
options = options || {}
|
|
87
|
+
options = options || {};
|
|
129
88
|
|
|
130
89
|
this.config.debug && console.log(`Preparing to send ${emails.length} emails ...`);
|
|
131
90
|
|
|
132
|
-
const htmlWarning =
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const emailsToSend: TCompleteEmail[] = emails.map(email => {
|
|
91
|
+
const htmlWarning =
|
|
92
|
+
this.app.env.profile === 'dev'
|
|
93
|
+
? `⚠️ This email has been sent for testing purposes. Please ignore it if you're not a developer.<br /><br />`
|
|
94
|
+
: '';
|
|
137
95
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
: email.from;
|
|
96
|
+
const emailsToSend: TCompleteEmail[] = emails.map((email) => {
|
|
97
|
+
const from: TPerson = email.from === undefined ? this.config.default.from : email.from;
|
|
141
98
|
|
|
142
|
-
const cc: TPerson[] = email.cc === undefined ? [] : Array.isArray(email.cc)
|
|
143
|
-
? email.cc
|
|
144
|
-
: [email.cc];
|
|
99
|
+
const cc: TPerson[] = email.cc === undefined ? [] : Array.isArray(email.cc) ? email.cc : [email.cc];
|
|
145
100
|
|
|
146
|
-
const to: TPerson[] = Array.isArray(email.to)
|
|
147
|
-
? email.to
|
|
148
|
-
: [email.to];
|
|
101
|
+
const to: TPerson[] = Array.isArray(email.to) ? email.to : [email.to];
|
|
149
102
|
|
|
150
103
|
if ('markdown' in email) {
|
|
151
|
-
|
|
152
|
-
return {
|
|
153
|
-
...email,
|
|
154
|
-
html: htmlWarning + markdown.render(email.markdown),
|
|
155
|
-
from,
|
|
156
|
-
to,
|
|
157
|
-
cc
|
|
158
|
-
}
|
|
159
|
-
|
|
104
|
+
return { ...email, html: htmlWarning + markdown.render(email.markdown), from, to, cc };
|
|
160
105
|
} else {
|
|
161
106
|
return {
|
|
162
107
|
...email,
|
|
163
|
-
html: htmlWarning + (typeof email.html ===
|
|
164
|
-
? email.html
|
|
165
|
-
: jsonToHtml(email.html)),
|
|
108
|
+
html: htmlWarning + (typeof email.html === 'string' ? email.html : jsonToHtml(email.html)),
|
|
166
109
|
from,
|
|
167
110
|
to,
|
|
168
|
-
cc
|
|
169
|
-
}
|
|
111
|
+
cc,
|
|
112
|
+
};
|
|
170
113
|
}
|
|
171
|
-
|
|
172
114
|
});
|
|
173
115
|
|
|
174
116
|
console.info(LogPrefix, `Sending ${emailsToSend.length} emails:`, emailsToSend[0].subject);
|
|
@@ -183,6 +125,5 @@ export default abstract class Email<TConfig extends Config>
|
|
|
183
125
|
}
|
|
184
126
|
|
|
185
127
|
await this.sendNow(emailsToSend);
|
|
186
|
-
|
|
187
128
|
}
|
|
188
|
-
}
|
|
129
|
+
}
|
|
@@ -2,52 +2,39 @@
|
|
|
2
2
|
- DEPENDANCES
|
|
3
3
|
----------------------------------*/
|
|
4
4
|
// Npm
|
|
5
|
-
import dayjs from 'dayjs';
|
|
5
|
+
import dayjs from 'dayjs';
|
|
6
6
|
import escapehtml from 'escape-html';
|
|
7
7
|
|
|
8
8
|
/*----------------------------------
|
|
9
9
|
- FONCTIONS
|
|
10
10
|
----------------------------------*/
|
|
11
|
-
export const espacesVersHtml = (txt: string) =>
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
export const espacesVersHtml = (txt: string) =>
|
|
12
|
+
txt
|
|
13
|
+
.replace(/(\n|\r)/g, '<br>') // Sauts de ligne
|
|
14
|
+
.replace(/(\t)/g, ' '.repeat(8)) // Tabulations
|
|
15
|
+
.replace(/ /g, ' '); // Espaces
|
|
16
|
+
/*.replace(/\"/g, '"') // Doubles quotes
|
|
16
17
|
.replace(/\'/g, "'") // Doubles quotes*/
|
|
17
18
|
|
|
18
|
-
export const jsonToHtml = (objet: {[cle: string]: any}, complet: boolean = false): string => {
|
|
19
|
-
|
|
19
|
+
export const jsonToHtml = (objet: { [cle: string]: any }, complet: boolean = false): string => {
|
|
20
20
|
let html: string[] = [];
|
|
21
21
|
|
|
22
22
|
for (const label in objet) {
|
|
23
|
-
|
|
24
23
|
let valeur = objet[label];
|
|
25
24
|
|
|
26
25
|
if (valeur === undefined || valeur === null) {
|
|
27
|
-
|
|
28
26
|
if (complet === true)
|
|
29
27
|
// quand undefined, JSON.stringify retourne aussi undefined
|
|
30
|
-
valeur = valeur === undefined
|
|
31
|
-
|
|
32
|
-
: JSON.stringify(valeur, null, 4);
|
|
33
|
-
else
|
|
34
|
-
continue;
|
|
35
|
-
|
|
28
|
+
valeur = valeur === undefined ? 'undefined' : JSON.stringify(valeur, null, 4);
|
|
29
|
+
else continue;
|
|
36
30
|
} else if (typeof valeur === 'object') {
|
|
37
|
-
|
|
38
|
-
if (valeur instanceof Date)
|
|
39
|
-
valeur = dayjs(valeur).format('DD/MM/YYYY HH:mm:ss');
|
|
40
|
-
|
|
31
|
+
if (valeur instanceof Date) valeur = dayjs(valeur).format('DD/MM/YYYY HH:mm:ss');
|
|
41
32
|
}
|
|
42
33
|
|
|
43
|
-
if (!valeur || typeof valeur !== 'string')
|
|
44
|
-
valeur = JSON.stringify(valeur, null, 4);
|
|
34
|
+
if (!valeur || typeof valeur !== 'string') valeur = JSON.stringify(valeur, null, 4);
|
|
45
35
|
|
|
46
|
-
html.push(
|
|
47
|
-
'<b>' + label + ':</b> ' + espacesVersHtml(escapehtml(valeur))
|
|
48
|
-
);
|
|
36
|
+
html.push('<b>' + label + ':</b> ' + espacesVersHtml(escapehtml(valeur)));
|
|
49
37
|
}
|
|
50
38
|
|
|
51
39
|
return html.join('<br>');
|
|
52
|
-
|
|
53
|
-
}
|
|
40
|
+
};
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
// Npm
|
|
6
6
|
import type { default as sharp, Sharp } from 'sharp';
|
|
7
7
|
import fs from 'fs-extra';
|
|
8
|
-
import got, { Method, Options } from 'got';
|
|
8
|
+
import got, { Method, Options, Response as GotResponse } from 'got';
|
|
9
9
|
|
|
10
10
|
// Node
|
|
11
11
|
import request from 'request';
|
|
12
12
|
|
|
13
13
|
// Core: general
|
|
14
|
-
import type { Application } from '@server/app';
|
|
15
|
-
import Service
|
|
14
|
+
import type { Application } from '@server/app/index';
|
|
15
|
+
import Service from '@server/app/service';
|
|
16
16
|
import { viaHttpCode } from '@common/errors';
|
|
17
17
|
|
|
18
18
|
// Local
|
|
@@ -25,75 +25,55 @@ import type FsDriver from '../disks/driver';
|
|
|
25
25
|
----------------------------------*/
|
|
26
26
|
|
|
27
27
|
export type Config = {
|
|
28
|
-
debug?: boolean
|
|
29
|
-
disk?: string
|
|
28
|
+
debug?: boolean;
|
|
29
|
+
disk?: string;
|
|
30
30
|
|
|
31
|
-
disks: DisksManager,
|
|
32
|
-
router?: TAnyRouter
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export type Hooks = {
|
|
31
|
+
disks: DisksManager<any, any, Application>;
|
|
32
|
+
router?: TAnyRouter;
|
|
33
|
+
};
|
|
36
34
|
|
|
37
|
-
}
|
|
35
|
+
export type Hooks = {};
|
|
38
36
|
|
|
39
37
|
/*----------------------------------
|
|
40
38
|
- TYPES
|
|
41
39
|
----------------------------------*/
|
|
42
40
|
|
|
43
41
|
export type TImageConfig = {
|
|
44
|
-
sharp: typeof sharp
|
|
45
|
-
width: number
|
|
46
|
-
height: number
|
|
47
|
-
fit: keyof sharp.FitEnum
|
|
48
|
-
quality: number
|
|
49
|
-
}
|
|
42
|
+
sharp: typeof sharp;
|
|
43
|
+
width: number;
|
|
44
|
+
height: number;
|
|
45
|
+
fit: keyof sharp.FitEnum;
|
|
46
|
+
quality: number;
|
|
47
|
+
};
|
|
50
48
|
|
|
51
49
|
/*----------------------------------
|
|
52
50
|
- CONST
|
|
53
51
|
----------------------------------*/
|
|
54
52
|
|
|
55
|
-
const LogPrefix = `[services][fetch]
|
|
53
|
+
const LogPrefix = `[services][fetch]`;
|
|
56
54
|
|
|
57
55
|
/*----------------------------------
|
|
58
56
|
- SERVICE
|
|
59
57
|
- Tools that helps to consume external resources (including apis, ..)
|
|
60
58
|
-----------------------------------*/
|
|
61
59
|
export default class FetchService extends Service<Config, Hooks, Application, Application> {
|
|
62
|
-
|
|
63
60
|
private disk?: FsDriver;
|
|
64
61
|
|
|
65
62
|
public async ready() {
|
|
66
|
-
|
|
67
|
-
if (this.config.disks)
|
|
68
|
-
this.disk = this.config.disks.get( this.config.disk );
|
|
69
|
-
|
|
63
|
+
if (this.config.disks) this.disk = this.config.disks.get(this.config.disk);
|
|
70
64
|
}
|
|
71
65
|
|
|
72
|
-
public async shutdown() {
|
|
73
|
-
|
|
74
|
-
}
|
|
66
|
+
public async shutdown() {}
|
|
75
67
|
|
|
76
68
|
/*----------------------------------
|
|
77
69
|
- EXTERNAL API REQUESTS
|
|
78
70
|
----------------------------------*/
|
|
79
71
|
|
|
80
|
-
public post(
|
|
81
|
-
url
|
|
82
|
-
data: {[k: string]: any},
|
|
83
|
-
options: {} = {}
|
|
84
|
-
) {
|
|
85
|
-
|
|
86
|
-
return this.request('POST', url, data, options);
|
|
87
|
-
|
|
72
|
+
public post(url: string, data: { [k: string]: any }, options: {} = {}) {
|
|
73
|
+
return this.send('POST', url, data, options);
|
|
88
74
|
}
|
|
89
75
|
|
|
90
|
-
public async
|
|
91
|
-
method: Method,
|
|
92
|
-
url: string,
|
|
93
|
-
data: {[k: string]: any},
|
|
94
|
-
options: Options = {}
|
|
95
|
-
) {
|
|
96
|
-
|
|
76
|
+
public async send(method: Method, url: string, data: { [k: string]: any }, options: Options = {}) {
|
|
97
77
|
// Parse url if router service is provided
|
|
98
78
|
if (this.config.router === undefined)
|
|
99
79
|
throw new Error(`Please bind the Router service to the Fetch service in order to contact APIs.`);
|
|
@@ -101,91 +81,80 @@ export default class FetchService extends Service<Config, Hooks, Application, Ap
|
|
|
101
81
|
url = this.config.router.url(url);
|
|
102
82
|
|
|
103
83
|
// Send request
|
|
104
|
-
const res = await got(url, {
|
|
84
|
+
const res = (await got(url, {
|
|
105
85
|
throwHttpErrors: false,
|
|
106
|
-
headers: {
|
|
107
|
-
'Accept': 'application/json',
|
|
108
|
-
},
|
|
86
|
+
headers: { Accept: 'application/json' },
|
|
109
87
|
method,
|
|
110
|
-
...(method === 'GET' ? {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
json: data
|
|
114
|
-
})
|
|
115
|
-
})
|
|
88
|
+
...(method === 'GET' ? { searchParams: data } : { json: data }),
|
|
89
|
+
...options,
|
|
90
|
+
})) as GotResponse<string>;
|
|
116
91
|
|
|
117
92
|
// Handle errors
|
|
118
93
|
if (res.statusCode !== 200) {
|
|
119
|
-
|
|
120
94
|
// Instanciate error from HTTP code
|
|
121
|
-
const error = viaHttpCode(
|
|
122
|
-
if (error)
|
|
123
|
-
throw error;
|
|
95
|
+
const error = viaHttpCode(res.statusCode, res.body);
|
|
96
|
+
if (error) throw error;
|
|
124
97
|
|
|
125
98
|
// Not catched via viaHttpCode
|
|
126
|
-
console.log(
|
|
127
|
-
throw new Error(
|
|
99
|
+
console.log('RESPONSE', res.body);
|
|
100
|
+
throw new Error('Error while contacting the API');
|
|
128
101
|
}
|
|
129
102
|
|
|
130
103
|
// Format & return response
|
|
131
|
-
return JSON.parse(
|
|
104
|
+
return JSON.parse(res.body);
|
|
132
105
|
}
|
|
133
106
|
|
|
134
107
|
/*----------------------------------
|
|
135
108
|
- IMAGES
|
|
136
109
|
----------------------------------*/
|
|
137
110
|
|
|
138
|
-
public toBuffer(
|
|
111
|
+
public toBuffer(uri: string): Promise<Buffer> {
|
|
139
112
|
return new Promise<Buffer>((resolve, reject) => {
|
|
140
113
|
request(uri, { encoding: null }, (err, res, body) => {
|
|
114
|
+
if (err) return reject(err);
|
|
141
115
|
|
|
142
|
-
if (
|
|
143
|
-
return reject(err);
|
|
144
|
-
|
|
145
|
-
if (!body)
|
|
146
|
-
return reject(`Body is empty for ${uri}.`);
|
|
116
|
+
if (!body) return reject(`Body is empty for ${uri}.`);
|
|
147
117
|
|
|
148
118
|
resolve(body);
|
|
149
|
-
})
|
|
150
|
-
})
|
|
119
|
+
});
|
|
120
|
+
});
|
|
151
121
|
}
|
|
152
122
|
|
|
153
|
-
public async image(
|
|
154
|
-
imageFileUrl: string,
|
|
155
|
-
imageMod: TImageConfig,
|
|
123
|
+
public async image(
|
|
124
|
+
imageFileUrl: string,
|
|
125
|
+
imageMod: TImageConfig,
|
|
156
126
|
saveToBucket: string,
|
|
157
127
|
saveToPath?: string,
|
|
158
|
-
disk?: string
|
|
128
|
+
disk?: string,
|
|
159
129
|
): Promise<Buffer | null> {
|
|
160
|
-
|
|
161
130
|
// Define target disk
|
|
162
|
-
if (this.disk === undefined)
|
|
163
|
-
throw new Error(`Please provide a Disks service in order to download files.`);
|
|
131
|
+
if (this.disk === undefined) throw new Error(`Please provide a Disks service in order to download files.`);
|
|
164
132
|
|
|
165
133
|
// Download
|
|
166
134
|
let imageBuffer: Buffer | null;
|
|
167
135
|
try {
|
|
168
|
-
imageBuffer = await this.toBuffer(
|
|
136
|
+
imageBuffer = await this.toBuffer(imageFileUrl);
|
|
169
137
|
} catch (error) {
|
|
170
138
|
console.error(LogPrefix, `Error while fetching image at ${imageFileUrl}:`, error);
|
|
171
139
|
return null;
|
|
172
140
|
}
|
|
173
141
|
|
|
174
142
|
if (imageMod) {
|
|
175
|
-
|
|
176
143
|
const { sharp, width, height, fit, quality } = imageMod;
|
|
177
144
|
|
|
178
145
|
// Resize
|
|
179
|
-
const processing = sharp(
|
|
146
|
+
const processing = sharp(imageBuffer)
|
|
180
147
|
// Max dimensions (save space)
|
|
181
|
-
.resize(width, height, { fit })
|
|
182
|
-
|
|
183
|
-
// Convert to webp and finalize
|
|
184
|
-
imageBuffer = await processing.webp({ quality }).toBuffer().catch(e => {
|
|
185
|
-
console.error(LogPrefix, `Error while processing image at ${imageFileUrl}:`, e);
|
|
186
|
-
return null;
|
|
187
|
-
})
|
|
148
|
+
.resize(width, height, { fit });
|
|
188
149
|
|
|
150
|
+
// Convert to webp and finalize
|
|
151
|
+
imageBuffer = await processing
|
|
152
|
+
.webp({ quality })
|
|
153
|
+
.toBuffer()
|
|
154
|
+
.catch((e) => {
|
|
155
|
+
console.error(LogPrefix, `Error while processing image at ${imageFileUrl}:`, e);
|
|
156
|
+
return null;
|
|
157
|
+
});
|
|
189
158
|
}
|
|
190
159
|
|
|
191
160
|
// Save file
|
|
@@ -197,5 +166,4 @@ export default class FetchService extends Service<Config, Hooks, Application, Ap
|
|
|
197
166
|
// We return the original, because Vibrant.js doesn't support webp
|
|
198
167
|
return imageBuffer;
|
|
199
168
|
}
|
|
200
|
-
|
|
201
|
-
}
|
|
169
|
+
}
|