proteum 1.0.2 → 2.0.0-1

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 (185) hide show
  1. package/AGENTS.md +101 -0
  2. package/agents/codex/AGENTS.md +95 -0
  3. package/agents/codex/CODING_STYLE.md +71 -0
  4. package/agents/codex/agents.md.zip +0 -0
  5. package/agents/codex/client/AGENTS.md +102 -0
  6. package/agents/codex/client/pages/AGENTS.md +35 -0
  7. package/agents/codex/server/routes/AGENTS.md +12 -0
  8. package/agents/codex/server/services/AGENTS.md +137 -0
  9. package/agents/codex/tests/AGENTS.md +8 -0
  10. package/cli/app/config.ts +13 -11
  11. package/cli/app/index.ts +74 -82
  12. package/cli/bin.js +1 -1
  13. package/cli/commands/build.ts +51 -14
  14. package/cli/commands/check.ts +19 -0
  15. package/cli/commands/deploy/app.ts +4 -8
  16. package/cli/commands/deploy/web.ts +16 -20
  17. package/cli/commands/dev.ts +189 -64
  18. package/cli/commands/devEvents.ts +106 -0
  19. package/cli/commands/init.ts +63 -57
  20. package/cli/commands/lint.ts +21 -0
  21. package/cli/commands/refresh.ts +18 -0
  22. package/cli/commands/typecheck.ts +18 -0
  23. package/cli/compiler/client/identite.ts +80 -53
  24. package/cli/compiler/client/index.ts +139 -213
  25. package/cli/compiler/common/bundleAnalysis.ts +94 -0
  26. package/cli/compiler/common/clientManifest.ts +67 -0
  27. package/cli/compiler/common/controllers.ts +288 -0
  28. package/cli/compiler/common/files/autres.ts +7 -18
  29. package/cli/compiler/common/files/images.ts +40 -37
  30. package/cli/compiler/common/files/style.ts +11 -22
  31. package/cli/compiler/common/generatedRouteModules.ts +368 -0
  32. package/cli/compiler/common/index.ts +31 -65
  33. package/cli/compiler/common/loaders/forbid-ssr-import.js +13 -0
  34. package/cli/compiler/common/rspackAliases.ts +13 -0
  35. package/cli/compiler/common/scripts.ts +37 -0
  36. package/cli/compiler/index.ts +781 -230
  37. package/cli/compiler/server/index.ts +59 -75
  38. package/cli/compiler/writeIfChanged.ts +21 -0
  39. package/cli/index.ts +71 -72
  40. package/cli/paths.ts +51 -57
  41. package/cli/print.ts +17 -11
  42. package/cli/tsconfig.json +5 -4
  43. package/cli/utils/agents.ts +100 -0
  44. package/cli/utils/check.ts +71 -0
  45. package/cli/utils/index.ts +1 -3
  46. package/cli/utils/keyboard.ts +8 -25
  47. package/cli/utils/runProcess.ts +30 -0
  48. package/client/app/component.tsx +29 -29
  49. package/client/app/index.ts +36 -57
  50. package/client/app/service.ts +7 -12
  51. package/client/app.tsconfig.json +2 -2
  52. package/client/components/Dialog/Manager.ssr.tsx +40 -0
  53. package/client/components/Dialog/Manager.tsx +119 -150
  54. package/client/components/Dialog/status.tsx +3 -3
  55. package/client/components/index.ts +1 -1
  56. package/client/components/types.d.ts +1 -3
  57. package/client/dev/hmr.ts +65 -0
  58. package/client/global.d.ts +2 -2
  59. package/client/hooks.ts +6 -9
  60. package/client/index.ts +2 -1
  61. package/client/islands/index.ts +7 -0
  62. package/client/islands/useDeferredModule.ts +199 -0
  63. package/client/pages/_layout/index.tsx +4 -12
  64. package/client/pages/useHeader.tsx +14 -21
  65. package/client/router.ts +27 -0
  66. package/client/services/router/components/Link.tsx +34 -27
  67. package/client/services/router/components/Page.tsx +6 -14
  68. package/client/services/router/components/router.ssr.tsx +36 -0
  69. package/client/services/router/components/router.tsx +63 -83
  70. package/client/services/router/index.tsx +185 -220
  71. package/client/services/router/request/api.ts +97 -119
  72. package/client/services/router/request/history.ts +2 -2
  73. package/client/services/router/request/index.ts +13 -12
  74. package/client/services/router/request/multipart.ts +72 -62
  75. package/client/services/router/response/index.tsx +68 -61
  76. package/client/services/router/response/page.ts +28 -32
  77. package/client/utils/dom.ts +17 -33
  78. package/common/app/index.ts +3 -3
  79. package/common/data/chaines/index.ts +22 -23
  80. package/common/data/dates.ts +35 -70
  81. package/common/data/markdown.ts +42 -39
  82. package/common/dev/serverHotReload.ts +26 -0
  83. package/common/errors/index.tsx +110 -142
  84. package/common/router/contracts.ts +29 -0
  85. package/common/router/index.ts +89 -108
  86. package/common/router/layouts.ts +34 -47
  87. package/common/router/pageSetup.ts +50 -0
  88. package/common/router/register.ts +53 -24
  89. package/common/router/request/api.ts +30 -36
  90. package/common/router/request/index.ts +2 -8
  91. package/common/router/response/index.ts +8 -15
  92. package/common/router/response/page.ts +70 -58
  93. package/common/utils.ts +1 -1
  94. package/doc/TODO.md +1 -1
  95. package/eslint.js +62 -0
  96. package/package.json +14 -49
  97. package/prettier.config.cjs +9 -0
  98. package/scripts/cleanup-generated-controllers.ts +62 -0
  99. package/scripts/fix-reference-app-typing.ts +490 -0
  100. package/scripts/refactor-client-app-imports.ts +244 -0
  101. package/scripts/refactor-client-pages.ts +587 -0
  102. package/scripts/refactor-server-controllers.ts +470 -0
  103. package/scripts/refactor-server-runtime-aliases.ts +360 -0
  104. package/scripts/restore-client-app-import-files.ts +41 -0
  105. package/scripts/restore-files-from-git-head.ts +20 -0
  106. package/scripts/update-codex-agents.ts +35 -0
  107. package/server/app/commands.ts +35 -64
  108. package/server/app/container/config.ts +48 -59
  109. package/server/app/container/console/index.ts +202 -248
  110. package/server/app/container/index.ts +33 -71
  111. package/server/app/controller/index.ts +61 -0
  112. package/server/app/index.ts +39 -105
  113. package/server/app/service/container.ts +41 -42
  114. package/server/app/service/index.ts +120 -147
  115. package/server/context.ts +1 -1
  116. package/server/index.ts +25 -1
  117. package/server/services/auth/index.ts +75 -115
  118. package/server/services/auth/router/index.ts +31 -32
  119. package/server/services/auth/router/request.ts +14 -16
  120. package/server/services/cron/CronTask.ts +13 -26
  121. package/server/services/cron/index.ts +14 -36
  122. package/server/services/disks/driver.ts +40 -58
  123. package/server/services/disks/drivers/local/index.ts +79 -90
  124. package/server/services/disks/drivers/s3/index.ts +116 -163
  125. package/server/services/disks/index.ts +23 -38
  126. package/server/services/email/index.ts +45 -104
  127. package/server/services/email/utils.ts +14 -27
  128. package/server/services/fetch/index.ts +53 -85
  129. package/server/services/prisma/Facet.ts +39 -91
  130. package/server/services/prisma/index.ts +74 -110
  131. package/server/services/router/generatedRuntime.ts +29 -0
  132. package/server/services/router/http/index.ts +78 -73
  133. package/server/services/router/http/multipart.ts +19 -42
  134. package/server/services/router/index.ts +378 -365
  135. package/server/services/router/request/api.ts +26 -25
  136. package/server/services/router/request/index.ts +44 -51
  137. package/server/services/router/request/service.ts +7 -11
  138. package/server/services/router/request/validation/zod.ts +111 -148
  139. package/server/services/router/response/index.ts +110 -125
  140. package/server/services/router/response/mask/Filter.ts +31 -72
  141. package/server/services/router/response/mask/index.ts +8 -15
  142. package/server/services/router/response/mask/selecteurs.ts +11 -25
  143. package/server/services/router/response/page/clientManifest.ts +25 -0
  144. package/server/services/router/response/page/document.tsx +199 -127
  145. package/server/services/router/response/page/index.tsx +89 -94
  146. package/server/services/router/service.ts +13 -15
  147. package/server/services/schema/index.ts +17 -26
  148. package/server/services/schema/request.ts +19 -33
  149. package/server/services/schema/router/index.ts +8 -11
  150. package/server/services/security/encrypt/aes/index.ts +15 -35
  151. package/server/utils/slug.ts +29 -35
  152. package/skills/clean-project-code/SKILL.md +63 -0
  153. package/skills/clean-project-code/agents/openai.yaml +4 -0
  154. package/tsconfig.common.json +4 -3
  155. package/tsconfig.json +4 -1
  156. package/types/aliases.d.ts +17 -21
  157. package/types/controller-input.test.ts +48 -0
  158. package/types/express-extra.d.ts +6 -0
  159. package/types/global/constants.d.ts +13 -0
  160. package/types/global/express-extra.d.ts +6 -0
  161. package/types/global/modules.d.ts +13 -16
  162. package/types/global/utils.d.ts +17 -49
  163. package/types/global/vendors.d.ts +62 -0
  164. package/types/icons.d.ts +65 -1
  165. package/types/uuid.d.ts +3 -0
  166. package/types/vendors.d.ts +62 -0
  167. package/cli/compiler/common/babel/index.ts +0 -170
  168. package/cli/compiler/common/babel/plugins/index.ts +0 -0
  169. package/cli/compiler/common/babel/plugins/services.ts +0 -586
  170. package/cli/compiler/common/babel/routes/imports.ts +0 -127
  171. package/cli/compiler/common/babel/routes/routes.ts +0 -1130
  172. package/client/services/captcha/index.ts +0 -67
  173. package/client/services/socket/index.ts +0 -147
  174. package/common/data/rte/nodes.ts +0 -83
  175. package/common/data/stats.ts +0 -90
  176. package/common/utils/rte.ts +0 -183
  177. package/server/services/auth/old.ts +0 -277
  178. package/server/services/cache/commands.ts +0 -41
  179. package/server/services/cache/index.ts +0 -297
  180. package/server/services/cache/service.json +0 -6
  181. package/server/services/socket/index.ts +0 -162
  182. package/server/services/socket/scope.ts +0 -226
  183. package/server/services/socket/service.json +0 -6
  184. package/server/services_old/SocketClient.ts +0 -92
  185. package/server/services_old/Token.old.ts +0 -97
@@ -3,16 +3,12 @@
3
3
  ----------------------------------*/
4
4
 
5
5
  // Npm
6
- import webpack from 'webpack';
7
- import fs from 'fs-extra';
8
-
9
- // Minimizers
10
- const TerserPlugin = require("terser-webpack-plugin");
11
- //var VirtualModulesPlugin = require('webpack-virtual-modules');
6
+ import { type Configuration } from '@rspack/core';
12
7
 
13
8
  // Core
14
9
  import cli from '@cli';
15
- import createCommonConfig, { TCompileMode, regex } from '../common';
10
+ import createCommonConfig, { TCompileMode, TCompileOutputTarget, regex } from '../common';
11
+ import { toRspackAliases } from '../common/rspackAliases';
16
12
 
17
13
  // Type
18
14
  import type { App } from '../../app';
@@ -35,45 +31,57 @@ import type { App } from '../../app';
35
31
  }*/
36
32
 
37
33
  const debug = false;
34
+ const ssrScriptExtensions = ['.ssr.ts', '.ssr.tsx'];
35
+
36
+ const getDevGeneratedRuntimeEntries = (app: App) => ({
37
+ __proteum_dev_routes: [app.paths.server.generated + '/routes.ts'],
38
+ __proteum_dev_controllers: [app.paths.server.generated + '/controllers.ts'],
39
+ });
38
40
 
39
41
  /*----------------------------------
40
42
  - CONFIG
41
43
  ----------------------------------*/
42
- export default function createCompiler( app: App, mode: TCompileMode ): webpack.Configuration {
43
-
44
+ export default function createCompiler(
45
+ app: App,
46
+ mode: TCompileMode,
47
+ outputTarget: TCompileOutputTarget = mode === 'dev' ? 'dev' : 'bin',
48
+ ): Configuration {
44
49
  debug && console.info(`Creating compiler for server (${mode}).`);
45
50
  const dev = mode === 'dev';
51
+ const outputPath = app.outputPath(outputTarget);
46
52
 
47
- const commonConfig = createCommonConfig(app, 'server', mode);
48
- const { aliases } = app.aliases.server.forWebpack({
49
- modulesPath: app.paths.root + '/node_modules'
50
- });
53
+ const commonConfig = createCommonConfig(app, 'server', mode, outputTarget);
54
+ const { aliases } = app.aliases.server.forWebpack({ modulesPath: app.paths.root + '/node_modules' });
51
55
 
52
56
  // We're not supposed in any case to import client services from server
53
- delete aliases["@client/services"];
54
- delete aliases["@/client/services"];
55
-
56
- debug && console.log(`[${mode}] node_modules dirs:`, commonConfig.resolveLoader?.modules,
57
- '\nModule aliases for webpack:', aliases);
58
- const config: webpack.Configuration = {
59
-
57
+ delete aliases['@client/services'];
58
+ delete aliases['@/client/services'];
59
+ const rspackAliases = toRspackAliases(aliases);
60
+ rspackAliases['@/client/router$'] = cli.paths.core.root + '/client/router.ts';
61
+
62
+ debug &&
63
+ console.log(
64
+ `[${mode}] node_modules dirs:`,
65
+ commonConfig.resolveLoader?.modules,
66
+ '\nModule aliases for rspack:',
67
+ rspackAliases,
68
+ );
69
+ const config: Configuration = {
60
70
  ...commonConfig,
61
71
 
62
72
  name: 'server',
63
73
  target: 'node',
64
74
  entry: {
65
- server: [
66
- cli.paths.coreRoot + '/server/index.ts'
67
- ],
75
+ server: [cli.paths.coreRoot + '/server/index.ts'],
76
+ ...(dev ? getDevGeneratedRuntimeEntries(app) : {}),
68
77
  },
69
78
 
70
79
  output: {
71
-
72
80
  pathinfo: dev,
73
81
 
74
82
  libraryTarget: 'commonjs2',
75
83
 
76
- path: app.paths.bin,
84
+ path: outputPath,
77
85
  filename: '[name].js',
78
86
  publicPath: '/',
79
87
  assetModuleFilename: 'public/[hash][ext]',
@@ -82,38 +90,32 @@ export default function createCompiler( app: App, mode: TCompileMode ): webpack.
82
90
  // HMR
83
91
  hotUpdateMainFilename: 'updates/[fullhash].hot-update.json',
84
92
  hotUpdateChunkFilename: 'updates/[id].[fullhash].hot-update.js',
85
-
86
93
  },
87
94
 
88
95
  externalsPresets: { node: true }, // in order to ignore built-in modules like path, fs, etc.
89
96
  externals: [
90
-
91
- './chunk-manifest.json',
92
- './asset-manifest.json',
97
+ './client-manifest.json',
93
98
 
94
99
  // node_modules
95
100
  function ({ request }, callback) {
96
-
97
- const shouldCompile = request !== undefined && (
101
+ const shouldCompile =
102
+ request !== undefined &&
98
103
  // Local files
99
- request[0] === '.' || request[0] === '/'
100
- ||
101
- // Aliased modules
102
- app.aliases.server.containsAlias(request)
103
- ||
104
- // TODO: proteum.conf: compile: include
105
- // Compile proteum modules
106
- request.startsWith('proteum')
107
- ||
108
- // Compile 5HTP modules
109
- request.startsWith('react-number-format') ||
110
- request.startsWith('@floating-ui')
111
- )
104
+ (request[0] === '.' ||
105
+ request[0] === '/' ||
106
+ // Aliased modules
107
+ app.aliases.server.containsAlias(request) ||
108
+ // TODO: proteum.conf: compile: include
109
+ // Compile proteum modules
110
+ request.startsWith('proteum') ||
111
+ // Compile 5HTP modules
112
+ request.startsWith('@mantine/') ||
113
+ request.startsWith('react-number-format') ||
114
+ request.startsWith('@floating-ui'));
112
115
 
113
116
  //console.log('isNodeModule', request, isNodeModule);
114
117
 
115
118
  if (!shouldCompile) {
116
-
117
119
  // Externalize to a commonjs module using the request path
118
120
  return callback(undefined, 'commonjs ' + request);
119
121
  }
@@ -124,12 +126,12 @@ export default function createCompiler( app: App, mode: TCompileMode ): webpack.
124
126
  ],
125
127
 
126
128
  resolve: {
127
-
128
129
  ...commonConfig.resolve,
129
130
 
130
- alias: aliases,
131
+ alias: rspackAliases,
131
132
 
132
- extensions: ['.ts', '.tsx', ".json", ".sql", ".js"],
133
+ // Prefer SSR-specific variants on the server when imports stay extensionless.
134
+ extensions: [...ssrScriptExtensions, '.ts', '.tsx', '.json', '.sql', '.js'],
133
135
  },
134
136
 
135
137
  module: {
@@ -140,7 +142,6 @@ export default function createCompiler( app: App, mode: TCompileMode ): webpack.
140
142
  {
141
143
  test: regex.scripts,
142
144
  include: [
143
-
144
145
  app.paths.root + '/client',
145
146
  cli.paths.core.root + '/client',
146
147
 
@@ -155,15 +156,12 @@ export default function createCompiler( app: App, mode: TCompileMode ): webpack.
155
156
  // Temp disabled because compile issue on vercel
156
157
  //...getCorePluginsList(app)
157
158
  ],
158
- rules: require('../common/babel')(app, 'server', dev)
159
- },
159
+ rules: require('../common/scripts')({ app, side: 'server', dev }),
160
+ },
160
161
 
161
162
  // Les pages étan tà la fois compilées dans le bundle client et serveur
162
163
  // On ne compile les ressources (css) qu'une seule fois (coté client)
163
- {
164
- test: regex.style,
165
- loader: 'null-loader'
166
- },
164
+ { test: regex.style, loader: 'null-loader' },
167
165
 
168
166
  ...require('../common/files/images')(app, dev, false),
169
167
 
@@ -179,33 +177,19 @@ export default function createCompiler( app: App, mode: TCompileMode ): webpack.
179
177
  ],
180
178
  },
181
179
 
182
- plugins: [
183
-
184
- ...(commonConfig.plugins || [])
185
- ],
180
+ plugins: [...(commonConfig.plugins || [])],
186
181
 
187
- optimization: {
188
- minimizer: dev ? [] : [
189
- new TerserPlugin({
190
- terserOptions: {
191
- // Consere les classnames
192
- //keep_classnames: true,
193
- //keep_fnames: true,
194
- }
195
- }),
196
- ]
197
- },
182
+ optimization: { minimizer: [] },
198
183
 
199
- // https://webpack.js.org/configuration/devtool/#devtool
200
- devtool: dev
201
- ? 'eval-source-map' // Recommended choice for development builds with high quality SourceMaps.
184
+ devtool: dev
185
+ ? 'eval-cheap-module-source-map' // Cheaper than eval-source-map while keeping usable module-level stack traces.
202
186
  : 'source-map', // Recommended choice for production builds with high quality SourceMaps.
203
187
 
204
- // eval-source-map n'est pas précis
188
+ // eval-source-map n'est pas précis
205
189
  /*devServer: {
206
190
  hot: true,
207
191
  },*/
208
192
  };
209
193
 
210
194
  return config;
211
- };
195
+ }
@@ -0,0 +1,21 @@
1
+ import path from 'path';
2
+ import fs from 'fs-extra';
3
+
4
+ const toBuffer = (content: string | Buffer) => (typeof content === 'string' ? Buffer.from(content) : content);
5
+
6
+ export default function writeIfChanged(filepath: string, content: string | Buffer) {
7
+ const nextContent = toBuffer(content);
8
+ const dirpath = path.dirname(filepath);
9
+
10
+ fs.ensureDirSync(dirpath);
11
+
12
+ if (fs.existsSync(filepath)) {
13
+ const currentContent = fs.readFileSync(filepath);
14
+
15
+ if (currentContent.equals(nextContent)) return false;
16
+ }
17
+
18
+ fs.writeFileSync(filepath, nextContent);
19
+
20
+ return true;
21
+ }
package/cli/index.ts CHANGED
@@ -17,13 +17,9 @@ import Paths from './paths';
17
17
  - TYPES
18
18
  ----------------------------------*/
19
19
 
20
- type TCliCommand = () => Promise<{
21
- run: () => Promise<void>
22
- }>
20
+ type TCliCommand = () => Promise<{ run: () => Promise<void> }>;
23
21
 
24
- type TArgsObject = {
25
- [key: string]: string | boolean | string[]
26
- }
22
+ type TArgsObject = { [key: string]: string | boolean | string[] };
27
23
 
28
24
  /*----------------------------------
29
25
  - CLASSE
@@ -32,17 +28,20 @@ type TArgsObject = {
32
28
  IMPORTANT: The CLI must be independant of the app instance and libs
33
29
  */
34
30
  export class CLI {
35
-
36
31
  // Context
37
32
  public args: TArgsObject = {};
38
-
33
+
34
+ public commandOptionDefaults: { [command: string]: TArgsObject } = {
35
+ dev: { port: '', cache: true },
36
+ build: { port: '', dev: false, prod: false, cache: false, analyze: false },
37
+ lint: { fix: false },
38
+ };
39
+
39
40
  public debug: boolean = false;
40
41
 
41
- public packageJson: {[key: string]: any};
42
+ public packageJson: { [key: string]: any };
42
43
 
43
- public constructor(
44
- public paths = new Paths( process.cwd() )
45
- ) {
44
+ public constructor(public paths = new Paths(process.cwd())) {
46
45
  this.debug && console.log(`[cli] 5HTP CLI`, process.env.npm_package_version);
47
46
 
48
47
  this.debug && console.log(`[cli] Apply aliases ...`);
@@ -59,107 +58,111 @@ export class CLI {
59
58
  // Les importations asynchrones permettent d'accéder à l'instance de cli via un import
60
59
  // WARN: We load commands asynchonously, so the aliases are applied before the file is imported
61
60
  public commands: { [name: string]: TCliCommand } = {
62
- "init": () => import('./commands/init'),
63
- "dev": () => import('./commands/dev'),
64
- "build": () => import('./commands/build'),
65
- }
61
+ init: () => import('./commands/init'),
62
+ dev: () => import('./commands/dev'),
63
+ refresh: () => import('./commands/refresh'),
64
+ build: () => import('./commands/build'),
65
+ typecheck: () => import('./commands/typecheck'),
66
+ lint: () => import('./commands/lint'),
67
+ check: () => import('./commands/check'),
68
+ };
66
69
 
67
70
  private loadPkg() {
68
71
  return fs.readJSONSync(this.paths.core.root + '/package.json');
69
72
  }
70
73
 
71
74
  public start() {
72
-
73
75
  const [, , commandName, ...argv] = process.argv;
74
76
 
75
- if (this.commands[commandName] === undefined)
76
- throw new Error(`Command ${commandName} does not exists.`);
77
+ if (this.commands[commandName] === undefined) throw new Error(`Command ${commandName} does not exists.`);
77
78
 
79
+ this.args = { ...(this.commandOptionDefaults[commandName] || {}) };
78
80
  this.args.workdir = process.cwd();
79
81
 
80
82
  let opt: string | null = null;
81
83
  for (const a of argv) {
84
+ if (a.startsWith('-')) {
85
+ opt = a.replace(/^-+/, '');
86
+ if (opt.length === 0) throw new Error(`Unknown option: ${a}`);
87
+
88
+ if (opt.startsWith('no-')) {
89
+ const booleanOpt = opt.substring(3);
90
+ if (!(booleanOpt in this.args)) throw new Error(`Unknown option: ${opt}`);
91
+ if (typeof this.args[booleanOpt] !== 'boolean')
92
+ throw new Error(`Option ${booleanOpt} does not support --no-${booleanOpt}.`);
82
93
 
83
- if (a[0] === '-') {
94
+ this.args[booleanOpt] = false;
95
+ opt = null;
96
+ continue;
97
+ }
84
98
 
85
- opt = a.substring(1);
86
- if (!(opt in this.args))
87
- throw new Error(`Unknown option: ${opt}`);
99
+ if (!(opt in this.args)) throw new Error(`Unknown option: ${opt}`);
88
100
 
89
101
  // Init with default value
90
- if (typeof this.args[opt] === "boolean")
102
+ if (typeof this.args[opt] === 'boolean') {
91
103
  this.args[opt] = true;
92
-
104
+ opt = null;
105
+ }
93
106
  } else if (opt !== null) {
94
-
95
107
  const curVal = this.args[opt];
96
108
 
97
- if (Array.isArray( curVal ))
98
- curVal.push(a);
99
- else
100
- this.args[opt] = a;
109
+ if (Array.isArray(curVal)) curVal.push(a);
110
+ else this.args[opt] = a;
101
111
 
102
112
  opt = null;
103
-
104
113
  } else {
105
-
106
- this.args[ a ] = true;
107
-
114
+ this.args[a] = true;
108
115
  }
109
116
  }
110
117
 
118
+ if (opt !== null && typeof this.args[opt] !== 'boolean') throw new Error(`Missing value for option: ${opt}`);
119
+
111
120
  this.runCommand(commandName);
112
121
  }
113
122
 
114
123
  public async runCommand(command: string) {
115
-
116
124
  this.debug && console.info(`Running command ${command}`, this.args);
117
125
 
118
126
  // Check existance
119
- if (this.commands[command] === undefined)
120
- throw new Error(`Command ${command} does not exists.`);
127
+ if (this.commands[command] === undefined) throw new Error(`Command ${command} does not exists.`);
121
128
 
122
129
  const runner = await this.commands[command]();
130
+ let exitCode = 0;
123
131
 
124
132
  // Running
125
- runner.run().then(() => {
126
-
127
- this.debug && console.info(`Command ${command} finished.`);
128
-
129
- }).catch((e) => {
130
-
131
- console.error(`Error during execution of ${command}:`, e);
132
-
133
- }).finally(() => {
134
-
135
- process.exit(0);
136
-
137
- })
133
+ runner
134
+ .run()
135
+ .then(() => {
136
+ this.debug && console.info(`Command ${command} finished.`);
137
+ })
138
+ .catch((e) => {
139
+ exitCode = 1;
140
+ console.error(`Error during execution of ${command}:`, e);
141
+ })
142
+ .finally(() => {
143
+ process.exit(exitCode);
144
+ });
138
145
  }
139
146
 
140
-
141
147
  public shell(...commands: string[]) {
142
-
143
148
  return new Promise<void>(async (resolve) => {
149
+ const fullCommand = commands
150
+ .map((command) => {
151
+ command = command.trim();
144
152
 
145
- const fullCommand = commands.map(command => {
153
+ if (command.endsWith(';')) command = command.substring(0, command.length - 1);
146
154
 
147
- command = command.trim();
148
-
149
- if (command.endsWith(';'))
150
- command = command.substring(0, command.length - 1);
151
-
152
- return command;
153
-
154
- }).join(';');
155
+ return command;
156
+ })
157
+ .join(';');
155
158
 
156
159
  console.log('$ ' + fullCommand);
157
160
 
158
161
  /*const tempFile = this.paths.app.root + '/.exec.sh';
159
162
  fs.outputFileSync(tempFile, '#! /bin/bash\n' + fullCommand);
160
163
  const wrappedCommand = `tilix --new-process -e bash -c 'chmod +x "${tempFile}"; "${tempFile}"; echo "Entrée pour continuer"; read a;'`;*/
161
- const wrappedCommand = `bash -c '${fullCommand}'`;
162
- console.log("Running command: " + wrappedCommand)
164
+ const wrappedCommand = `bash -c '${fullCommand}'`;
165
+ console.log('Running command: ' + wrappedCommand);
163
166
  //await this.waitForInput('enter');
164
167
 
165
168
  const proc = cp.spawn(wrappedCommand, [], {
@@ -167,23 +170,19 @@ export class CLI {
167
170
  detached: false,
168
171
  // Permer de lancer les commandes via des chaines pures (autrement, il faut separer chaque arg dans un tableau)
169
172
  // https://stackoverflow.com/questions/23487363/how-can-i-parse-a-string-into-appropriate-arguments-for-child-process-spawn
170
- shell: true
173
+ shell: true,
171
174
  });
172
175
 
173
- console.log( proc.exitCode );
176
+ console.log(proc.exitCode);
174
177
 
175
178
  proc.on('exit', function () {
176
-
177
179
  //fs.removeSync(tempFile);
178
180
 
179
- console.log("Command finished.");
181
+ console.log('Command finished.');
180
182
  resolve();
181
- })
182
-
183
+ });
183
184
  });
184
-
185
185
  }
186
-
187
186
  }
188
187
 
189
- export default new CLI()
188
+ export default new CLI();