5htp 0.4.6 → 0.5.9

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 (41) hide show
  1. package/{src/app → app}/config.ts +7 -7
  2. package/app/index.ts +196 -0
  3. package/{src/commands → commands}/dev.ts +2 -2
  4. package/{src/commands → commands}/init.ts +1 -1
  5. package/{src/compiler → compiler}/client/identite.ts +1 -1
  6. package/{src/compiler → compiler}/client/index.ts +6 -6
  7. package/{src/compiler → compiler}/common/babel/index.ts +20 -2
  8. package/{src/compiler → compiler}/common/babel/plugins/injection-dependances/index.ts +2 -2
  9. package/{src/compiler → compiler}/common/babel/plugins/queries/index.ts +1 -1
  10. package/compiler/common/babel/plugins/services.ts +247 -0
  11. package/{src/compiler → compiler}/common/babel/routes/imports.ts +1 -1
  12. package/{src/compiler → compiler}/common/babel/routes/routes.ts +148 -39
  13. package/{src/compiler → compiler}/common/files/style.ts +3 -3
  14. package/{src/compiler → compiler}/common/plugins/indexage/icones-svg/index.ts +2 -2
  15. package/{src/compiler → compiler}/index.ts +150 -37
  16. package/{src/compiler → compiler}/server/index.ts +18 -11
  17. package/package.json +7 -5
  18. package/{src/paths.ts → paths.ts} +3 -4
  19. package/tsconfig.json +3 -2
  20. package/src/app/index.ts +0 -111
  21. package/src/compiler/common/babel/plugins/services.ts +0 -209
  22. /package/{src/commands → commands}/build.ts +0 -0
  23. /package/{src/commands → commands}/deploy/app.ts +0 -0
  24. /package/{src/commands → commands}/deploy/web.ts +0 -0
  25. /package/{src/compiler → compiler}/common/babel/plugins/form.ts +0 -0
  26. /package/{src/compiler → compiler}/common/babel/plugins/icones-svg.ts +0 -0
  27. /package/{src/compiler → compiler}/common/babel/plugins/index.ts +0 -0
  28. /package/{src/compiler → compiler}/common/babel/plugins/injection-dependances/remplacerFonction.ts +0 -0
  29. /package/{src/compiler → compiler}/common/files/autres.ts +0 -0
  30. /package/{src/compiler → compiler}/common/files/images.ts +0 -0
  31. /package/{src/compiler → compiler}/common/index.ts +0 -0
  32. /package/{src/compiler → compiler}/common/plugins/indexage/_utils/Stringify.ts +0 -0
  33. /package/{src/compiler → compiler}/common/plugins/indexage/_utils/annotations.ts +0 -0
  34. /package/{src/compiler → compiler}/common/plugins/indexage/_utils/iterateur.ts +0 -0
  35. /package/{src/compiler → compiler}/common/plugins/indexage/index.ts +0 -0
  36. /package/{src/compiler → compiler}/common/plugins/indexage/indexeur.ts +0 -0
  37. /package/{src/compiler → compiler}/common/plugins/indexage/injection-dependances/index.ts +0 -0
  38. /package/{src/index.ts → index.ts} +0 -0
  39. /package/{src/print.ts → print.ts} +0 -0
  40. /package/{src/utils → utils}/index.ts +0 -0
  41. /package/{src/utils → utils}/keyboard.ts +0 -0
@@ -15,7 +15,7 @@ import fs from 'fs-extra';
15
15
  import yaml from 'yaml';
16
16
 
17
17
  // Types
18
- import type { TEnvConfig } from '../../../core/src/server/app/container/config';
18
+ import type { TEnvConfig } from '../../core/server/app/container/config';
19
19
 
20
20
  /*----------------------------------
21
21
  - LOADE
@@ -38,12 +38,12 @@ export default class ConfigParser {
38
38
  public env(): TEnvConfig {
39
39
  // We assume that when we run 5htp dev, we're in local
40
40
  // Otherwise, we're in production environment (docker)
41
- return process.env.NODE_ENV === 'development' ? {
42
- name: 'local',
43
- profile: 'dev',
44
- } : {
45
- name: 'server',
46
- profile: 'prod',
41
+ console.log("[app] Using environment:", process.env.NODE_ENV);
42
+ const envFileName = this.appDir + '/env.yaml';
43
+ const envFile = this.loadYaml( envFileName );
44
+ return {
45
+ ...envFile,
46
+ version: 'CLI'
47
47
  }
48
48
  }
49
49
 
package/app/index.ts ADDED
@@ -0,0 +1,196 @@
1
+ /*----------------------------------
2
+ - DEPENDANCES
3
+ ----------------------------------*/
4
+
5
+ // npm
6
+ import path from 'path';
7
+ import TsAlias from 'ts-alias';
8
+ import fs from 'fs-extra';
9
+
10
+ // Cre
11
+ import cli from '..';
12
+
13
+ // Specific
14
+ import ConfigParser from './config';
15
+ import type { TEnvConfig } from '../../core/server/app/container/config';
16
+
17
+ /*----------------------------------
18
+ - TYPES
19
+ ----------------------------------*/
20
+
21
+ export type TAppSide = 'server' | 'client'
22
+
23
+ /*----------------------------------
24
+ - SERVICE
25
+ ----------------------------------*/
26
+ export class App {
27
+
28
+ // config
29
+ // WARNING: High level config files (env and services) shouldn't be loaded from the CLI
30
+ // The CLI will be run on CircleCI, and no env file should be sent to this service
31
+ public identity: Config.Identity;
32
+
33
+ public env: TEnvConfig;
34
+
35
+ public packageJson: {[key: string]: any};
36
+
37
+ public paths = {
38
+
39
+ root: cli.paths.appRoot,
40
+ bin: path.join( cli.paths.appRoot, 'bin'),
41
+ data: path.join( cli.paths.appRoot, 'var', 'data'),
42
+ public: path.join( cli.paths.appRoot, 'public'),
43
+ pages: path.join( cli.paths.appRoot, 'client', 'pages'),
44
+ cache: path.join( cli.paths.appRoot, '.cache'),
45
+
46
+ client: {
47
+ generated: path.join( cli.paths.appRoot, 'client', '.generated')
48
+ },
49
+ server: {
50
+ generated: path.join( cli.paths.appRoot, 'server', '.generated'),
51
+ configs: path.join( cli.paths.appRoot, 'server', 'app')
52
+ },
53
+
54
+ withAlias: (filename: string, side: TAppSide) =>
55
+ this.aliases[side].apply(filename),
56
+
57
+ withoutAlias: (filename: string, side: TAppSide) =>
58
+ this.aliases[side].realpath(filename),
59
+ }
60
+
61
+ public containerServices = [
62
+ //'Services',
63
+ 'Environment',
64
+ 'Identity',
65
+ /*'Application',
66
+ 'Path',
67
+ 'Event'*/
68
+ ]
69
+
70
+ public constructor() {
71
+
72
+ cli.debug && console.log(`[cli] Loading app config ...`);
73
+ const configParser = new ConfigParser( cli.paths.appRoot );
74
+ this.identity = configParser.identity();
75
+ this.env = configParser.env();
76
+ this.packageJson = this.loadPkg();
77
+
78
+ }
79
+
80
+ /*----------------------------------
81
+ - ALIAS
82
+ ----------------------------------*/
83
+
84
+ public aliases = {
85
+ client: new TsAlias({
86
+ rootDir: this.paths.root + '/client',
87
+ modulesDir: [
88
+ cli.paths.appRoot + '/node_modules',
89
+ cli.paths.coreRoot + '/node_modules'
90
+ ],
91
+ debug: false
92
+ }),
93
+ server: new TsAlias({
94
+ rootDir: this.paths.root + '/server',
95
+ modulesDir: [
96
+ cli.paths.appRoot + '/node_modules',
97
+ cli.paths.coreRoot + '/node_modules'
98
+ ],
99
+ debug: false
100
+ }),
101
+ }
102
+
103
+ private loadPkg() {
104
+ return fs.readJSONSync(this.paths.root + '/package.json');
105
+ }
106
+
107
+ /*----------------------------------
108
+ - WARMUP (Services awareness)
109
+ ----------------------------------*/
110
+
111
+ public registered = {}
112
+
113
+ public use( referenceName: string ) {
114
+
115
+ // We don't check because all service are not regstered when we register subservices
116
+ /*if (this.registered[referenceName] === undefined) {
117
+ throw new Error(`Service ${referenceName} is not registered`);
118
+ }*/
119
+
120
+ return {
121
+ refTo: referenceName,
122
+ }
123
+ }
124
+
125
+ public setup(...args: [
126
+ // { user: app.setup('Core/User') }
127
+ serviceId: string,
128
+ serviceConfig?: TServiceConfig,
129
+ serviceSubservices?: TServiceSubservices
130
+ ] | [
131
+ // app.setup('User', 'Core/User')
132
+ serviceName: string,
133
+ serviceId: string,
134
+ serviceConfig?: TServiceConfig,
135
+ serviceSubservices?: TServiceSubservices
136
+ ]) {
137
+
138
+ // Registration to app root
139
+ if (typeof args[1] === 'string') {
140
+
141
+ const [name, id, config, subservices] = args;
142
+
143
+ const service = { id, name, config, subservices }
144
+
145
+ this.registered[name] = service;
146
+
147
+ // Scoped to a parent service
148
+ } else {
149
+
150
+ const [id, config, subservices] = args;
151
+
152
+ const service = { id, config, subservices }
153
+
154
+ return service;
155
+ }
156
+ }
157
+
158
+ public async warmup() {
159
+
160
+ console.log("env", this.env);
161
+
162
+
163
+ // Require all config files in @/server/config
164
+ const configDir = path.resolve(cli.paths.appRoot, 'server', 'config');
165
+ const configFiles = fs.readdirSync(configDir);
166
+ for (const configFile of configFiles) {
167
+ console.log("Loading config file:", configFile);
168
+ require( path.resolve(configDir, configFile) );
169
+ }
170
+
171
+ // Wait 2 seconds
172
+ await new Promise(resolve => setTimeout(resolve, 1000));
173
+
174
+ // Load subservices
175
+ // for (const serviceName in this.registered) {
176
+ // const service = this.registered[serviceName];
177
+
178
+ // const subservices = {}
179
+ // if (service.subservices) {
180
+ // const list = service.subservices( this.registered );
181
+ // for (const subservice of list) {
182
+
183
+ // subservices[subservice.name] = list[];
184
+
185
+ // }
186
+ // }
187
+ // service.subservices = subservices;
188
+ // }
189
+
190
+ // console.log("SERVICES", this.registered);
191
+ }
192
+ }
193
+
194
+ export const app = new App
195
+
196
+ export default app
@@ -7,7 +7,7 @@ import fs from 'fs-extra';
7
7
  import { spawn, ChildProcess } from 'child_process';
8
8
 
9
9
  // Cor elibs
10
- import cli from '../';
10
+ import cli from '..';
11
11
  import Keyboard from '../utils/keyboard';
12
12
 
13
13
  // Configs
@@ -51,7 +51,7 @@ export const run = () => new Promise<void>(async () => {
51
51
  // Ignore updated from:
52
52
  // - Node modules except 5HTP core (framework dev mode)
53
53
  // - Generated files during runtime (cause infinite loop. Ex: models.d.ts)
54
- ignored: /(node_modules\/(?!5htp\-core\/src\/))|(\.generated\/)/
54
+ ignored: /(node_modules\/(?!5htp\-core\/))|(\.generated\/)/
55
55
 
56
56
  //aggregateTimeout: 1000,
57
57
  }, async (error, stats) => {
@@ -10,7 +10,7 @@ import cmd from 'node-cmd';
10
10
  import replaceOnce from 'replace-once';
11
11
 
12
12
  // Cor elibs
13
- import cli from '../';
13
+ import cli from '..';
14
14
 
15
15
  // Configs
16
16
  const filesToConfig = [
@@ -19,7 +19,7 @@ export default async ( app: App ) => {
19
19
 
20
20
  const identity = app.identity;
21
21
 
22
- const response = await favicons( app.paths.root + '/src/client/assets/identity/logo.svg', {
22
+ const response = await favicons( app.paths.root + '/client/assets/identity/logo.svg', {
23
23
 
24
24
  path: '/assets/img/identite/favicons/',
25
25
  appName: identity.name,
@@ -75,7 +75,7 @@ export default function createCompiler( app: App, mode: TCompileMode ): webpack.
75
75
  // https://github.com/webpack-contrib/webpack-hot-middleware#config
76
76
  cli.paths.core.root + '/node_modules' + '/webpack-hot-middleware/client?name=client&reload=true',
77
77
  ] : []),*/
78
- cli.paths.core.root + '/src/client/index.ts'
78
+ cli.paths.core.root + '/client/index.ts'
79
79
  ]
80
80
  },
81
81
 
@@ -110,13 +110,13 @@ export default function createCompiler( app: App, mode: TCompileMode ): webpack.
110
110
  test: regex.scripts,
111
111
  include: [
112
112
 
113
- app.paths.root + '/src/client',
114
- cli.paths.core.root + '/src/client',
113
+ app.paths.root + '/client',
114
+ cli.paths.core.root + '/client',
115
115
 
116
- app.paths.root + '/src/common',
117
- cli.paths.core.root + '/src/common',
116
+ app.paths.root + '/common',
117
+ cli.paths.core.root + '/common',
118
118
 
119
- app.paths.root + '/src/server/.generated/models.ts',
119
+ app.paths.root + '/server/.generated/models.ts',
120
120
 
121
121
  ],
122
122
  rules: require('../common/babel')(app, 'client', dev)
@@ -42,7 +42,25 @@ module.exports = (app: App, side: TAppSide, dev: boolean): webpack.RuleSetRule[]
42
42
  }
43
43
 
44
44
  return [{
45
- loader: 'babel-loader',
45
+ loader: require.resolve('babel-loader'),
46
+ exclude: (filePath) => {
47
+ // 1) If not in "node_modules" at all => transpile it
48
+ if (!filePath.includes('node_modules')) {
49
+ return false;
50
+ }
51
+
52
+ // 2) If it’s "node_modules/5htp-core" but NOT "node_modules/5htp-core/node_modules",
53
+ // then transpile. Otherwise, exclude.
54
+ if (
55
+ filePath.includes('node_modules/5htp-core') &&
56
+ !filePath.includes('node_modules/5htp-core/node_modules')
57
+ ) {
58
+ return false;
59
+ }
60
+
61
+ // 3) Everything else in node_modules is excluded
62
+ return true;
63
+ },
46
64
  options: {
47
65
 
48
66
  // https://github.com/babel/babel-loader#options
@@ -83,7 +101,7 @@ module.exports = (app: App, side: TAppSide, dev: boolean): webpack.RuleSetRule[]
83
101
  // NOTE: On résoud les plugins et presets directement ici
84
102
  // Autrement, babel-loader les cherchera dans projet/node_modules
85
103
 
86
- //[require("@babel/plugin-proposal-decorators"), { "legacy": true }],
104
+ [require("@babel/plugin-proposal-decorators"), { "legacy": true }],
87
105
 
88
106
  [require('@babel/plugin-proposal-class-properties'), { "loose": true }],
89
107
 
@@ -12,9 +12,9 @@ import cli from '@cli';
12
12
  /*----------------------------------
13
13
  - WEBPACK RULE
14
14
  ----------------------------------*/
15
- const globServices = app.paths.root + '/src/server/services/**/*.ts';
15
+ const globServices = app.paths.root + '/server/services/**/*.ts';
16
16
  const globModuleService = '@app/server/services/**';
17
- const globRoutes = app.paths.root + '/src/server/routes/**/*.ts';
17
+ const globRoutes = app.paths.root + '/server/routes/**/*.ts';
18
18
 
19
19
  module.exports = {
20
20
  test: [globRoutes, globServices],
@@ -48,7 +48,7 @@ function Plugin (babel) {
48
48
 
49
49
  this.fichier = filename;
50
50
 
51
- const prefixeRoot = root + '/src/'
51
+ const prefixeRoot = root;
52
52
  this.dossier = path.dirname(filename).substring(prefixeRoot.length)
53
53
  },
54
54
  visitor: {
@@ -0,0 +1,247 @@
1
+ /*----------------------------------
2
+ - DEPENDANCES
3
+ ----------------------------------*/
4
+
5
+ // Npm
6
+ import * as types from '@babel/types'
7
+ import type { PluginObj } from '@babel/core';
8
+
9
+ // Core
10
+ import cli from '@cli';
11
+ import { App, TAppSide } from '../../../../app';
12
+
13
+ /*----------------------------------
14
+ - WEBPACK RULE
15
+ ----------------------------------*/
16
+
17
+ type TOptions = {
18
+ side: TAppSide,
19
+ app: App,
20
+ debug?: boolean
21
+ }
22
+
23
+ /**
24
+ * Extended source type: now includes "models"
25
+ * so we can differentiate how we rewrite references.
26
+ */
27
+ type TImportSource = 'container' | 'application' | 'models';
28
+
29
+ module.exports = (options: TOptions) => (
30
+ [Plugin, options]
31
+ )
32
+
33
+ /*----------------------------------
34
+ - PLUGIN
35
+ ----------------------------------*/
36
+ function Plugin(babel, { app, side, debug }: TOptions) {
37
+
38
+ const t = babel.types as typeof types;
39
+
40
+ /*
41
+ Transforms:
42
+ import { MyService, Environment } from '@app';
43
+ import { MyModel } from '@models';
44
+ ...
45
+ MyService.method();
46
+ Environment.name;
47
+ MyModel.someCall();
48
+
49
+ To:
50
+ import container from '<path>/server/app/container';
51
+ ...
52
+ container.Environment.name;
53
+ this.app.MyService.method();
54
+ this.app.Models.client.MyModel.someCall();
55
+
56
+ Processed files:
57
+ @/server/config
58
+ @/server/routes
59
+ @/server/services
60
+ */
61
+
62
+ const plugin: PluginObj<{
63
+
64
+ debug: boolean,
65
+
66
+ filename: string,
67
+ processFile: boolean,
68
+
69
+ // Count how many total imports we transform
70
+ importedCount: number,
71
+
72
+ // For every local identifier, store info about how it should be rewritten
73
+ importedReferences: {
74
+ [localName: string]: {
75
+ imported: string, // The original “imported” name
76
+ bindings: any, // reference paths
77
+ source: TImportSource // container | application | models
78
+ }
79
+ }
80
+
81
+ // Tally how many references per kind
82
+ bySource: { [s in TImportSource]: number }
83
+ }> = {
84
+
85
+ pre(state) {
86
+ this.filename = state.opts.filename as string;
87
+ this.processFile = (
88
+ this.filename.startsWith(cli.paths.appRoot + '/server/config')
89
+ ||
90
+ this.filename.startsWith(cli.paths.appRoot + '/server/routes')
91
+ ||
92
+ this.filename.startsWith(cli.paths.appRoot + '/server/services')
93
+ );
94
+
95
+ this.importedReferences = {};
96
+ this.bySource = {
97
+ container: 0,
98
+ application: 0,
99
+ models: 0
100
+ };
101
+ this.importedCount = 0;
102
+ this.debug = debug || false;
103
+ },
104
+
105
+ visitor: {
106
+
107
+ /**
108
+ * Detect import statements from '@app' or '@models'
109
+ */
110
+ ImportDeclaration(path) {
111
+ if (!this.processFile) return;
112
+
113
+ const source = path.node.source.value;
114
+ if (source !== '@app' && source !== '@models') {
115
+ return;
116
+ }
117
+
118
+ // For '@app' and '@models', gather imported symbols
119
+ for (const specifier of path.node.specifiers) {
120
+ if (specifier.type !== 'ImportSpecifier') continue;
121
+ if (specifier.imported.type !== 'Identifier') continue;
122
+
123
+ this.importedCount++;
124
+
125
+ let importSource: TImportSource;
126
+ if (source === '@app') {
127
+ // Distinguish whether it's a container service or an application service
128
+ if (app.containerServices.includes(specifier.imported.name)) {
129
+ importSource = 'container';
130
+ } else {
131
+ importSource = 'application';
132
+ }
133
+ } else {
134
+ // source === '@models'
135
+ importSource = 'models';
136
+ }
137
+
138
+ this.importedReferences[specifier.local.name] = {
139
+ imported: specifier.imported.name,
140
+ bindings: path.scope.bindings[specifier.local.name].referencePaths,
141
+ source: importSource
142
+ };
143
+
144
+ this.bySource[importSource]++;
145
+ }
146
+
147
+ // Remove the original import line(s) and replace with any needed new import
148
+ // For @app imports, we might import "container" if needed
149
+ // For @models, we don’t import anything
150
+ const replaceWith: any[] = [];
151
+
152
+ // If this line had container references, add a default import for container
153
+ // Example: import container from '<root>/server/app/container'
154
+ if (source === '@app' && this.bySource.container > 0) {
155
+ replaceWith.push(
156
+ t.importDeclaration(
157
+ [t.importDefaultSpecifier(t.identifier('container'))],
158
+ t.stringLiteral(
159
+ cli.paths.core.root + '/server/app/container'
160
+ )
161
+ )
162
+ );
163
+ }
164
+
165
+ // Replace the original import statement with our new import(s) if any
166
+ // or remove it entirely if no container references exist.
167
+ path.replaceWithMultiple(replaceWith);
168
+ },
169
+
170
+ /**
171
+ * Rewrite references to the imports
172
+ */
173
+ Identifier(path) {
174
+ if (!this.processFile || this.importedCount === 0) {
175
+ return;
176
+ }
177
+
178
+ const name = path.node.name;
179
+ const ref = this.importedReferences[name];
180
+ if (!ref || !ref.bindings) {
181
+ return;
182
+ }
183
+
184
+ // Find a specific binding that hasn't been replaced yet
185
+ let foundBinding = undefined;
186
+ for (const binding of ref.bindings) {
187
+ if (!binding.replaced && path.getPathLocation() === binding.getPathLocation()) {
188
+ foundBinding = binding;
189
+ break;
190
+ }
191
+ }
192
+ if (!foundBinding) {
193
+ return;
194
+ }
195
+
196
+ // Mark as replaced to avoid loops
197
+ foundBinding.replaced = true;
198
+
199
+ // Based on the source, replace the identifier with the proper MemberExpression
200
+ if (ref.source === 'container') {
201
+ // container.[identifier]
202
+ // e.g. container.Environment
203
+ path.replaceWith(
204
+ t.memberExpression(
205
+ t.identifier('container'),
206
+ path.node
207
+ )
208
+ );
209
+ }
210
+ else if (ref.source === 'application') {
211
+ // this.app.[identifier]
212
+ // e.g. this.app.MyService
213
+ path.replaceWith(
214
+ t.memberExpression(
215
+ t.memberExpression(
216
+ t.thisExpression(),
217
+ t.identifier('app')
218
+ ),
219
+ path.node
220
+ )
221
+ );
222
+ }
223
+ else if (ref.source === 'models') {
224
+ // this.app.Models.client.[identifier]
225
+ // e.g. this.app.Models.client.MyModel
226
+ path.replaceWith(
227
+ t.memberExpression(
228
+ t.memberExpression(
229
+ t.memberExpression(
230
+ t.memberExpression(
231
+ t.thisExpression(),
232
+ t.identifier('app')
233
+ ),
234
+ t.identifier('Models')
235
+ ),
236
+ t.identifier('client')
237
+ ),
238
+ path.node
239
+ )
240
+ );
241
+ }
242
+ }
243
+ }
244
+ };
245
+
246
+ return plugin;
247
+ }
@@ -13,7 +13,7 @@ import cli from '@cli';
13
13
  import type { TAppSide, default as App } from '@cli/app';
14
14
 
15
15
  // Resources
16
- const routesToPreload = require( cli.paths.appRoot + '/src/client/pages/preload.json' );
16
+ const routesToPreload = require( cli.paths.appRoot + '/client/pages/preload.json' );
17
17
 
18
18
  /*----------------------------------
19
19
  - CONFIG