5htp 0.0.2
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/package.json +94 -0
- package/src/commands/build.ts +32 -0
- package/src/commands/deploy/app.ts +29 -0
- package/src/commands/deploy/web.ts +62 -0
- package/src/commands/dev.ts +100 -0
- package/src/compiler/client/identite.ts +70 -0
- package/src/compiler/client/index.ts +335 -0
- package/src/compiler/common/babel/index.ts +261 -0
- package/src/compiler/common/babel/plugins/form.ts +191 -0
- package/src/compiler/common/babel/plugins/icones-svg.ts +350 -0
- package/src/compiler/common/babel/plugins/importations.ts +337 -0
- package/src/compiler/common/babel/plugins/injection-dependances/index.ts +223 -0
- package/src/compiler/common/babel/plugins/injection-dependances/remplacerFonction.ts +226 -0
- package/src/compiler/common/babel/plugins/models.ts +241 -0
- package/src/compiler/common/babel/plugins/pages.ts +185 -0
- package/src/compiler/common/babel/plugins/queries/index.ts +166 -0
- package/src/compiler/common/files/autres.ts +37 -0
- package/src/compiler/common/files/images.ts +19 -0
- package/src/compiler/common/files/style.ts +64 -0
- package/src/compiler/common/index.ts +148 -0
- package/src/compiler/common/plugins/indexage/_utils/Stringify.ts +72 -0
- package/src/compiler/common/plugins/indexage/_utils/annotations.ts +88 -0
- package/src/compiler/common/plugins/indexage/_utils/iterateur.ts +52 -0
- package/src/compiler/common/plugins/indexage/icones-svg/index.ts +198 -0
- package/src/compiler/common/plugins/indexage/index.ts +132 -0
- package/src/compiler/common/plugins/indexage/indexeur.ts +13 -0
- package/src/compiler/common/plugins/indexage/injection-dependances/index.ts +68 -0
- package/src/compiler/index.ts +86 -0
- package/src/compiler/server/index.ts +177 -0
- package/src/index.ts +192 -0
- package/src/paths.ts +158 -0
- package/src/print.ts +12 -0
- package/src/utils/index.ts +22 -0
- package/src/utils/keyboard.ts +78 -0
- package/tsconfig.json +38 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Npm
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { PluginObj } from '@babel/core';
|
|
8
|
+
import * as types from '@babel/types'
|
|
9
|
+
|
|
10
|
+
/*----------------------------------
|
|
11
|
+
- REGEX
|
|
12
|
+
----------------------------------*/
|
|
13
|
+
const cheminClasseQuery = '@serveur/database/jsql/query/runner';
|
|
14
|
+
|
|
15
|
+
const regFichierModele = /^[a-z]+\/serveur\/modeles\//i;
|
|
16
|
+
|
|
17
|
+
/*----------------------------------
|
|
18
|
+
- WEBPACK RULE
|
|
19
|
+
----------------------------------*/
|
|
20
|
+
module.exports = {// /serveur/**.ts */
|
|
21
|
+
test: /\/serveur\/(.*)\.(ts)$/i,
|
|
22
|
+
plugins: [
|
|
23
|
+
[Plugin]
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
/*----------------------------------
|
|
29
|
+
- PLUGIN
|
|
30
|
+
----------------------------------*/
|
|
31
|
+
function Plugin (babel) {
|
|
32
|
+
|
|
33
|
+
const t = babel.types as typeof types;
|
|
34
|
+
|
|
35
|
+
const plugin: PluginObj<{
|
|
36
|
+
fichier: string,
|
|
37
|
+
dossier: string
|
|
38
|
+
}> = {
|
|
39
|
+
pre(state) {
|
|
40
|
+
|
|
41
|
+
const { filename, root } = state.opts;
|
|
42
|
+
|
|
43
|
+
if (!filename)
|
|
44
|
+
throw new Error(`Impossible d'obtenir le chemin du fichier actuellement rraité par le plugin`);
|
|
45
|
+
|
|
46
|
+
if (!root)
|
|
47
|
+
throw new Error(`Impossible d'obtenir le chemin de la racine du projet`);
|
|
48
|
+
|
|
49
|
+
this.fichier = filename;
|
|
50
|
+
|
|
51
|
+
const prefixeRoot = root + '/src/'
|
|
52
|
+
this.dossier = path.dirname(filename).substring(prefixeRoot.length)
|
|
53
|
+
},
|
|
54
|
+
visitor: {
|
|
55
|
+
ImportDeclaration(instruction) {
|
|
56
|
+
|
|
57
|
+
if (!(
|
|
58
|
+
instruction.node.specifiers.length === 1
|
|
59
|
+
&&
|
|
60
|
+
instruction.node.specifiers[0].type === 'ImportDefaultSpecifier'
|
|
61
|
+
))
|
|
62
|
+
return;
|
|
63
|
+
|
|
64
|
+
const cheminImportFichier = instruction.node.source.value;
|
|
65
|
+
const importDefault = instruction.node.specifiers[0];
|
|
66
|
+
|
|
67
|
+
/* Recherche de:
|
|
68
|
+
import PublicScope from './Public/index.sql';
|
|
69
|
+
*/
|
|
70
|
+
if (
|
|
71
|
+
// Suffise SQL = déjà traité, ou intention de garder le SQL
|
|
72
|
+
!importDefault.local.name.endsWith('SQL')
|
|
73
|
+
&&
|
|
74
|
+
cheminImportFichier.endsWith('.sql')
|
|
75
|
+
) {
|
|
76
|
+
|
|
77
|
+
// Extraction des infos
|
|
78
|
+
const nomVarScope = importDefault.local.name;
|
|
79
|
+
const nomImportSql = nomVarScope + 'SQL';
|
|
80
|
+
const cheminCompletImport = path.join(this.dossier, cheminImportFichier);
|
|
81
|
+
|
|
82
|
+
// Génère un ID unique basé sur le chemin
|
|
83
|
+
let cheminScope: string = cheminCompletImport;
|
|
84
|
+
const isModelScope = regFichierModele.test(cheminCompletImport);
|
|
85
|
+
if (isModelScope) {
|
|
86
|
+
// Mission.Public
|
|
87
|
+
const nomModele = path.basename(this.dossier);
|
|
88
|
+
cheminScope = nomModele + '.' + cheminCompletImport.substring(
|
|
89
|
+
this.dossier.length + 1, // +1 pour le dernier slash
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
cheminScope = cheminScope
|
|
94
|
+
.substring(0, cheminScope.length - 4) // Vire l'extension .sql
|
|
95
|
+
.replace(/\//g, '.');
|
|
96
|
+
|
|
97
|
+
if (cheminScope.endsWith('.index'))
|
|
98
|
+
cheminScope = cheminScope.substring(0, cheminScope.length - 6)
|
|
99
|
+
|
|
100
|
+
// Renommage de l'import du sql et instanciaiton de la query
|
|
101
|
+
// NOTE: On ne skip pas, puisque les imports ont été suffixés de SQL
|
|
102
|
+
//instruction.skip();
|
|
103
|
+
let remplacement = []
|
|
104
|
+
|
|
105
|
+
/* Création factory */
|
|
106
|
+
remplacement.push(
|
|
107
|
+
|
|
108
|
+
// + import PublicScopeSql from './Public/index.sql';
|
|
109
|
+
t.importDeclaration(
|
|
110
|
+
[t.importDefaultSpecifier(t.identifier(nomImportSql))],
|
|
111
|
+
t.stringLiteral(cheminImportFichier)
|
|
112
|
+
),
|
|
113
|
+
|
|
114
|
+
// + const PublicScope = new String( PublicScopeSql );
|
|
115
|
+
t.variableDeclaration('const', [
|
|
116
|
+
t.variableDeclarator(
|
|
117
|
+
t.identifier(nomVarScope),
|
|
118
|
+
t.newExpression(
|
|
119
|
+
t.identifier('String'),
|
|
120
|
+
[t.identifier(nomImportSql)]
|
|
121
|
+
)
|
|
122
|
+
)
|
|
123
|
+
]),
|
|
124
|
+
|
|
125
|
+
// + PublicScope.id = 'earn/missions/Mission/Public/index';
|
|
126
|
+
t.expressionStatement(
|
|
127
|
+
t.assignmentExpression(
|
|
128
|
+
'=',
|
|
129
|
+
t.memberExpression(
|
|
130
|
+
t.identifier( nomVarScope ),
|
|
131
|
+
t.identifier('id')
|
|
132
|
+
),
|
|
133
|
+
t.stringLiteral(cheminScope)
|
|
134
|
+
)
|
|
135
|
+
),
|
|
136
|
+
|
|
137
|
+
// + PublicScope.sourceFile = 'earn/missions/Mission/Public/index.sql'
|
|
138
|
+
t.expressionStatement(
|
|
139
|
+
t.assignmentExpression(
|
|
140
|
+
'=',
|
|
141
|
+
t.memberExpression(
|
|
142
|
+
t.identifier( nomVarScope ),
|
|
143
|
+
t.identifier('sourceFile')
|
|
144
|
+
),
|
|
145
|
+
t.stringLiteral(cheminCompletImport)
|
|
146
|
+
)
|
|
147
|
+
),
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
/*console.log(`[babel][plugin][queries]`,
|
|
151
|
+
this.fichier, cheminCompletImport, '\n',
|
|
152
|
+
recast.print( t.program(remplacement) ).code,
|
|
153
|
+
cheminScope
|
|
154
|
+
);*/
|
|
155
|
+
|
|
156
|
+
// Remplacement
|
|
157
|
+
instruction.replaceWithMultiple(remplacement);
|
|
158
|
+
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
return plugin;
|
|
166
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { staticAssetName } from '../../../paths';
|
|
2
|
+
|
|
3
|
+
module.exports = (dev: boolean, client: boolean) => ([
|
|
4
|
+
|
|
5
|
+
// Allow to use ?raw at the end of the module path to iport the raw content only
|
|
6
|
+
// Example: import VisualParserSource from './Parsers/visual.js?raw';
|
|
7
|
+
{
|
|
8
|
+
resourceQuery: /raw/,
|
|
9
|
+
type: 'asset/source',
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
// Client uniquement: Retourne le fichier correspondant au fichier dans le dossier public
|
|
13
|
+
{
|
|
14
|
+
test: /\.(xml|ico|wav|mp3)$/,
|
|
15
|
+
//loader: 'file-loader',
|
|
16
|
+
type: 'asset/resource',
|
|
17
|
+
generator: {
|
|
18
|
+
filename: staticAssetName
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
// Texte brut
|
|
23
|
+
{
|
|
24
|
+
type: 'asset/source',
|
|
25
|
+
test: /\.(md|hbs|sql|txt|csv)$/,
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
// Polices dans un fichier distinc dans le dossier dédié
|
|
29
|
+
{
|
|
30
|
+
test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
|
|
31
|
+
//loader: 'file-loader',
|
|
32
|
+
type: 'asset/resource',
|
|
33
|
+
generator: {
|
|
34
|
+
filename: 'fonts/[name].[ext]'
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
])
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { staticAssetName } from '../../../paths';
|
|
2
|
+
import type webpack from 'webpack';
|
|
3
|
+
|
|
4
|
+
module.exports = (dev: boolean, client: boolean): webpack.RuleSetRule[] => {
|
|
5
|
+
|
|
6
|
+
return [{
|
|
7
|
+
test: /\.(bmp|gif|jpg|jpeg|png|ico|svg)$/,
|
|
8
|
+
type: 'asset',
|
|
9
|
+
parser: {
|
|
10
|
+
dataUrlCondition: {
|
|
11
|
+
// https://webpack.js.org/guides/asset-modules/#general-asset-type
|
|
12
|
+
// < 4kb = importation inline
|
|
13
|
+
// > 4kb = référence à l'url
|
|
14
|
+
maxSize: 4 * 1024 // 4kb
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
}]
|
|
19
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Plugons
|
|
2
|
+
import MiniCssExtractPlugin from "mini-css-extract-plugin";
|
|
3
|
+
import lessToJs from 'less-vars-to-js';
|
|
4
|
+
|
|
5
|
+
import fs from 'fs-extra';
|
|
6
|
+
import cli from '@cli';
|
|
7
|
+
|
|
8
|
+
module.exports = (dev: Boolean, client: boolean) => {
|
|
9
|
+
|
|
10
|
+
const paletteLess = fs.readFileSync( cli.paths.app.src + '/client/assets/theme.less', 'utf8');
|
|
11
|
+
const themeVars = lessToJs(paletteLess, { resolveVariables: true, stripPrefix: true });
|
|
12
|
+
|
|
13
|
+
return [
|
|
14
|
+
|
|
15
|
+
// Apply PostCSS plugins including autoprefixer
|
|
16
|
+
{
|
|
17
|
+
loader: MiniCssExtractPlugin.loader
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
// Process external/third-party styles
|
|
21
|
+
{
|
|
22
|
+
exclude: [/*process.env.framework + '/kernel', */cli.paths.app.src],
|
|
23
|
+
loader: 'css-loader',
|
|
24
|
+
options: {
|
|
25
|
+
sourceMap: dev
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
|
|
29
|
+
// Process internal/project styles (from src folder)
|
|
30
|
+
{
|
|
31
|
+
include: [/*process.env.framework + '/kernel', */cli.paths.app.src],
|
|
32
|
+
loader: 'css-loader',
|
|
33
|
+
options: {
|
|
34
|
+
// CSS Loader https://github.com/webpack/css-loader
|
|
35
|
+
importLoaders: 1,
|
|
36
|
+
sourceMap: dev
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
test: /\.less$/,
|
|
42
|
+
loader: 'less-loader',
|
|
43
|
+
options: {
|
|
44
|
+
lessOptions: {
|
|
45
|
+
// RAPPEL: Rallonge considéralement le temps de compilation
|
|
46
|
+
// Pour math.random
|
|
47
|
+
//javascriptEnabled: true
|
|
48
|
+
|
|
49
|
+
// Défault = parens-division depuis 4.0.0
|
|
50
|
+
// https://lesscss.org/usage/#less-options-math
|
|
51
|
+
math: 'always',
|
|
52
|
+
|
|
53
|
+
globalVars: themeVars
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
/*{
|
|
59
|
+
test: /\.scss/,
|
|
60
|
+
loader: process.env.framework + '/node_modules/sass-loader',
|
|
61
|
+
}*/
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// npm
|
|
6
|
+
import webpack from 'webpack';
|
|
7
|
+
import dayjs from 'dayjs';
|
|
8
|
+
|
|
9
|
+
// Plugins
|
|
10
|
+
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
|
|
11
|
+
import PluginIndexage from './plugins/indexage';
|
|
12
|
+
import IconesSvg from './plugins/indexage/icones-svg';
|
|
13
|
+
import InjectDeps from './plugins/indexage/injection-dependances';
|
|
14
|
+
|
|
15
|
+
// Core
|
|
16
|
+
import { TAppSide } from '@cli';
|
|
17
|
+
import cli from '../..';
|
|
18
|
+
|
|
19
|
+
/*----------------------------------
|
|
20
|
+
- CONSTANTS
|
|
21
|
+
----------------------------------*/
|
|
22
|
+
|
|
23
|
+
export const regex = {
|
|
24
|
+
scripts: /\.(ts|tsx)$/,
|
|
25
|
+
style: /\.(css|less|scss)$/,
|
|
26
|
+
images: /\.(bmp|gif|jpg|jpeg|png|ico|svg)$/, // SVG gérés par SVGR
|
|
27
|
+
fonts: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
|
|
28
|
+
staticAssetName: /*isDebug ? '[name].[ext].[hash:8]' :*/ '[hash:8][ext]',
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/*----------------------------------
|
|
32
|
+
- TYPES
|
|
33
|
+
----------------------------------*/
|
|
34
|
+
|
|
35
|
+
export type TCompileMode = 'dev' | 'prod'
|
|
36
|
+
|
|
37
|
+
/*----------------------------------
|
|
38
|
+
- BASE CONFIG
|
|
39
|
+
----------------------------------*/
|
|
40
|
+
|
|
41
|
+
export default function createCommonConfig( side: TAppSide, mode: TCompileMode ): webpack.Configuration {
|
|
42
|
+
|
|
43
|
+
const dev = mode === 'dev';
|
|
44
|
+
const config: webpack.Configuration = {
|
|
45
|
+
|
|
46
|
+
// Project root
|
|
47
|
+
context: cli.paths.app.root,
|
|
48
|
+
|
|
49
|
+
mode: dev ? 'development' : 'production',
|
|
50
|
+
|
|
51
|
+
resolveLoader: {
|
|
52
|
+
// Recherche des loaders dans framework/node_modules (psinon, webpack cherche dans le projet)
|
|
53
|
+
modules: [
|
|
54
|
+
cli.paths.core.root + '/node_modules'
|
|
55
|
+
],
|
|
56
|
+
mainFields: ['loader', 'main'],
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
plugins: [
|
|
60
|
+
|
|
61
|
+
// https://webpack.js.org/plugins/define-plugin/
|
|
62
|
+
new webpack.DefinePlugin({
|
|
63
|
+
|
|
64
|
+
__DEV__: dev,
|
|
65
|
+
SERVER: side === 'server',
|
|
66
|
+
BUILD_DATE: JSON.stringify(dayjs().format('YY.MM.DD-HH.mm')),
|
|
67
|
+
|
|
68
|
+
CORE_PATH: JSON.stringify(cli.paths.core.root),
|
|
69
|
+
APP_PATH: JSON.stringify(cli.paths.app.root),
|
|
70
|
+
APP_NAME: JSON.stringify(cli.identity.web.title),
|
|
71
|
+
|
|
72
|
+
}),
|
|
73
|
+
|
|
74
|
+
new PluginIndexage(side === 'client' ? {
|
|
75
|
+
'icones-svg': new IconesSvg,
|
|
76
|
+
} : {
|
|
77
|
+
//'injection-dependances': new InjectDeps,
|
|
78
|
+
}),
|
|
79
|
+
|
|
80
|
+
...(cli.args.analyze === side ? [
|
|
81
|
+
|
|
82
|
+
new BundleAnalyzerPlugin({
|
|
83
|
+
defaultSizes: 'stat',
|
|
84
|
+
openAnalyzer: false
|
|
85
|
+
}),
|
|
86
|
+
|
|
87
|
+
] : []),
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
...(dev ? [
|
|
92
|
+
|
|
93
|
+
// HMR
|
|
94
|
+
//new webpack.HotModuleReplacementPlugin()
|
|
95
|
+
|
|
96
|
+
] : []),
|
|
97
|
+
|
|
98
|
+
],
|
|
99
|
+
|
|
100
|
+
resolve: {
|
|
101
|
+
|
|
102
|
+
// Empêche le remplatcement des chemins vers les liens symboliques par leur vrai chemin
|
|
103
|
+
// Permet de conserver le chemin des packages enregistrés via npm link
|
|
104
|
+
// Equivalent tsconfig: preserveSymlinks: true
|
|
105
|
+
symlinks: false,
|
|
106
|
+
|
|
107
|
+
/*modules: [
|
|
108
|
+
cli.paths.core.root + '/node_modules',
|
|
109
|
+
cli.paths.app.root + '/node_modules',
|
|
110
|
+
]*/
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
// Turn off performance processing because we utilize
|
|
114
|
+
// our own hints via the FileSizeReporter
|
|
115
|
+
performance: false,
|
|
116
|
+
|
|
117
|
+
// Don't attempt to continue if there are any errors.
|
|
118
|
+
bail: !dev,
|
|
119
|
+
|
|
120
|
+
// When true, Can cause troubles on re-compiling the client side
|
|
121
|
+
// "webpack" The "path" argument must be of type string. Received undefined
|
|
122
|
+
// https://github.com/webpack/webpack/issues/12616
|
|
123
|
+
// Update: Hum it's fixed, just had to update webpack deps
|
|
124
|
+
cache: dev,
|
|
125
|
+
|
|
126
|
+
profile: true,
|
|
127
|
+
|
|
128
|
+
// Pour bundle-stats
|
|
129
|
+
// https://github.com/relative-ci/bundle-stats/tree/master/packages/cli#webpack-configuration
|
|
130
|
+
stats: {
|
|
131
|
+
cached: dev,
|
|
132
|
+
cachedAssets: dev,
|
|
133
|
+
chunks: dev,
|
|
134
|
+
chunkModules: dev,
|
|
135
|
+
colors: true,
|
|
136
|
+
hash: dev,
|
|
137
|
+
modules: dev,
|
|
138
|
+
reasons: dev,
|
|
139
|
+
timings: true,
|
|
140
|
+
version: dev,
|
|
141
|
+
errorDetails: true
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return config;
|
|
147
|
+
|
|
148
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const placeholder: string = '____PLACEHOLDER____';
|
|
2
|
+
const balises = {
|
|
3
|
+
fonction: '[fonction]',
|
|
4
|
+
methode: '[methode]'
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const regRemplacements = new RegExp('("([^"]+)": )?"' + placeholder + '"', 'g');
|
|
8
|
+
|
|
9
|
+
// Permet de transformer un objet en chaine json sans niquer les fonctions
|
|
10
|
+
export default ( obj: object, fonctions: string[] = [] ): string => {
|
|
11
|
+
|
|
12
|
+
var fns: [string, string][] = [];
|
|
13
|
+
|
|
14
|
+
// Remplace les fonctions par un placeholder et tranforme en json
|
|
15
|
+
var json = JSON.stringify(obj, (key: string, value: any): string => {
|
|
16
|
+
|
|
17
|
+
const func: boolean = typeof value === 'function';
|
|
18
|
+
const ref_fonction: boolean = typeof value === 'string' && value.startsWith( balises.fonction );
|
|
19
|
+
const ref_methode: boolean = typeof value === 'string' && value.startsWith( balises.methode );
|
|
20
|
+
|
|
21
|
+
if (fonctions.includes(key) || func || ref_fonction || ref_methode) {
|
|
22
|
+
|
|
23
|
+
if (func)
|
|
24
|
+
value = value.toString();
|
|
25
|
+
else if (ref_fonction)
|
|
26
|
+
value = value.substring( balises.fonction.length );
|
|
27
|
+
else if (ref_methode)
|
|
28
|
+
value = value.substring( balises.methode.length );
|
|
29
|
+
|
|
30
|
+
fns.push([ value, ref_methode ? 'methode' : 'fonction' ]);
|
|
31
|
+
|
|
32
|
+
return placeholder;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return value;
|
|
36
|
+
}, 4);
|
|
37
|
+
|
|
38
|
+
// Remplace les placeholders par la fonction brute sans les guillemets
|
|
39
|
+
json = json.replace(regRemplacements, (match: string, contnom: string, nom: string): string => {
|
|
40
|
+
const func = fns.shift();
|
|
41
|
+
if (Array.isArray(func)) {
|
|
42
|
+
|
|
43
|
+
const [ fonction, type ] = func;
|
|
44
|
+
|
|
45
|
+
// La fonction est dans un tableau
|
|
46
|
+
if (nom === undefined)
|
|
47
|
+
return fonction;
|
|
48
|
+
else
|
|
49
|
+
return type === 'methode'
|
|
50
|
+
// nom() { ... }
|
|
51
|
+
? nom + fonction
|
|
52
|
+
// "nom": () => { ... }
|
|
53
|
+
: '"'+ nom +'": ' + fonction;
|
|
54
|
+
|
|
55
|
+
return fonction ? fonction : '';
|
|
56
|
+
|
|
57
|
+
} else
|
|
58
|
+
return '';
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// retire les quotes
|
|
62
|
+
json = json.replace(/\"([a-zA-Z]+)\"\:/gm, '$1:');
|
|
63
|
+
|
|
64
|
+
// Correction pour les méthodes de classe
|
|
65
|
+
// Remplace <nom>: <args> => { par <nom><args> {
|
|
66
|
+
json = json.replace(
|
|
67
|
+
/([a-zA-Z]+)\:\s*(\([a-zA-Z\,\s]*\))\s*\=\>\s*\{/gmi,
|
|
68
|
+
'$1$2 {'
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
return json;
|
|
72
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
import fs from 'fs-extra';
|
|
5
|
+
|
|
6
|
+
/*----------------------------------
|
|
7
|
+
- TYPE
|
|
8
|
+
----------------------------------*/
|
|
9
|
+
type TDonnees = {[cle: string]: string | number};
|
|
10
|
+
|
|
11
|
+
/*----------------------------------
|
|
12
|
+
- FONCTION
|
|
13
|
+
----------------------------------*/
|
|
14
|
+
export default function lireAnnotations<TRetour = TDonnees>( fichier: string ): TRetour | undefined {
|
|
15
|
+
|
|
16
|
+
let annotations: TRetour = {} as TRetour;
|
|
17
|
+
let lectureAnnotations: boolean = false;
|
|
18
|
+
|
|
19
|
+
// Lecture de chaque ligne
|
|
20
|
+
const lignes = fs.readFileSync(fichier, 'utf-8').split('\n');
|
|
21
|
+
for (let ligne of lignes) {
|
|
22
|
+
|
|
23
|
+
// Debut des annotations
|
|
24
|
+
if (ligne === "/* ~~~~~~~~~~~~~~~~") {
|
|
25
|
+
|
|
26
|
+
lectureAnnotations = true;
|
|
27
|
+
|
|
28
|
+
// Fin des anotations
|
|
29
|
+
} else if (ligne === "~~~~~~~~~~~~~~~~ */") {
|
|
30
|
+
|
|
31
|
+
return annotations;
|
|
32
|
+
|
|
33
|
+
// Lecture des annotations
|
|
34
|
+
} else if (lectureAnnotations) {
|
|
35
|
+
|
|
36
|
+
// Retire le "* " au debut de la ligne
|
|
37
|
+
ligne = ligne.substring(2).trim();
|
|
38
|
+
// Ligne vide
|
|
39
|
+
if (ligne.length === 0)
|
|
40
|
+
continue;
|
|
41
|
+
|
|
42
|
+
// Niveau indentation
|
|
43
|
+
//const indentation = ligne.match(/^( )*/)
|
|
44
|
+
//const indentLevel = indentation === null ? 0 : indentation[0].length;
|
|
45
|
+
|
|
46
|
+
// cle: valeur
|
|
47
|
+
if (ligne.includes(': ')) {
|
|
48
|
+
|
|
49
|
+
// Décomposition clé / valeur
|
|
50
|
+
let [cle, valeur] = ligne.split(': ') as [string, any];
|
|
51
|
+
cle = cle.trim().toLowerCase();
|
|
52
|
+
|
|
53
|
+
// retire le commentaire
|
|
54
|
+
const poscommentaire = valeur.indexOf(' //')
|
|
55
|
+
if (poscommentaire !== -1)
|
|
56
|
+
valeur = valeur.substring(0, poscommentaire);
|
|
57
|
+
valeur = valeur.trim();
|
|
58
|
+
|
|
59
|
+
// Met en minuscules
|
|
60
|
+
if (cle) {
|
|
61
|
+
|
|
62
|
+
// Correction type valeur
|
|
63
|
+
if (valeur === 'true')
|
|
64
|
+
valeur = true;
|
|
65
|
+
else if (valeur === 'false')
|
|
66
|
+
valeur = false;
|
|
67
|
+
else if (!isNaN(Number(valeur)))
|
|
68
|
+
valeur = parseFloat(valeur);
|
|
69
|
+
|
|
70
|
+
// Référencement
|
|
71
|
+
if (annotations[cle] === undefined)
|
|
72
|
+
annotations[cle] = valeur;
|
|
73
|
+
// Valeur déjà existante, regroupement dans un tableau
|
|
74
|
+
else if (!Array.isArray(annotations[cle]))
|
|
75
|
+
annotations[cle] = [annotations[cle], valeur];
|
|
76
|
+
// Déjà en tableau, ajout élement
|
|
77
|
+
else
|
|
78
|
+
annotations[cle] = [...annotations[cle], valeur];
|
|
79
|
+
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const path = require('path')
|
|
2
|
+
const fs = require('fs')
|
|
3
|
+
|
|
4
|
+
export default function iterateur(
|
|
5
|
+
dir: string,
|
|
6
|
+
func: (fichier: string, ext: string, cheminRelatif: string, dossier: string) => void,
|
|
7
|
+
extensions: string[] = [],
|
|
8
|
+
blacklist: string[] = [],
|
|
9
|
+
func_sinon?: (fichier: string) => void,
|
|
10
|
+
dir_root?: string
|
|
11
|
+
) {
|
|
12
|
+
|
|
13
|
+
if (dir_root === undefined)
|
|
14
|
+
dir_root = dir;
|
|
15
|
+
|
|
16
|
+
// Lecture du contenu du dossier
|
|
17
|
+
const elements = fs.readdirSync(dir);
|
|
18
|
+
for (const file of elements) {
|
|
19
|
+
|
|
20
|
+
const file_relatif = dir + '/' + file;
|
|
21
|
+
|
|
22
|
+
// Pas dans la blacklist
|
|
23
|
+
if ((!blacklist || !blacklist.includes( file ))) {
|
|
24
|
+
|
|
25
|
+
// Récup chemin complet
|
|
26
|
+
const file_complet = path.resolve(dir, file);
|
|
27
|
+
|
|
28
|
+
// Extension sans le point
|
|
29
|
+
const ext = path.extname( file ).substring(1);
|
|
30
|
+
|
|
31
|
+
// Recup infos element
|
|
32
|
+
const stat = fs.statSync(file_complet);
|
|
33
|
+
|
|
34
|
+
// Dossier = recursion
|
|
35
|
+
if (stat && stat.isDirectory())
|
|
36
|
+
|
|
37
|
+
iterateur( file_relatif, func, extensions, blacklist, func_sinon, dir_root );
|
|
38
|
+
|
|
39
|
+
else if (extensions.includes( ext )) {
|
|
40
|
+
|
|
41
|
+
let chemin = file_relatif.substring(dir_root.length + 1, file_relatif.length - ext.length - 1)
|
|
42
|
+
if (chemin.endsWith('/index'))
|
|
43
|
+
chemin = chemin.substring(0, chemin.length - 6);
|
|
44
|
+
|
|
45
|
+
func( file_relatif, ext, chemin, dir );
|
|
46
|
+
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
} else if (func_sinon)
|
|
50
|
+
func_sinon( file_relatif );
|
|
51
|
+
};
|
|
52
|
+
}
|