5htp 0.0.9 → 0.2.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/package.json +5 -4
- package/skeleton/src/client/components/LoginModal.tsx +1 -1
- package/skeleton/src/client/pages/app/_layout/index.tsx +1 -1
- package/skeleton/src/client/pages/landing/_layout/index.tsx +1 -1
- package/skeleton/src/client/tsconfig.json +0 -4
- package/skeleton/src/server/services/auth/index.ts +4 -12
- package/src/app/config.ts +1 -11
- package/src/app/index.ts +2 -1
- package/src/compiler/client/index.ts +7 -3
- package/src/compiler/common/babel/index.ts +26 -126
- package/src/compiler/common/babel/plugins/index.ts +0 -0
- package/src/compiler/common/babel/plugins/{models.ts → models.old.ts} +0 -0
- package/src/compiler/common/babel/plugins/services.ts +163 -0
- package/src/compiler/common/babel/routes/imports.ts +129 -0
- package/src/compiler/common/babel/routes/routes.ts +279 -0
- package/src/compiler/common/babel/{plugins/pages.ts → routes/routes_old.ts} +6 -41
- package/src/compiler/common/utils/fixNpmLink.ts +2 -2
- package/src/compiler/index.ts +6 -0
- package/src/compiler/server/index.ts +10 -8
- package/src/index.ts +6 -2
- package/src/paths.ts +31 -11
- package/src/compiler/common/babel/plugins/importations.ts +0 -337
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Npm
|
|
6
|
+
import * as types from '@babel/types'
|
|
7
|
+
import type { PluginObj, NodePath } from '@babel/core';
|
|
8
|
+
import generate from '@babel/generator';
|
|
9
|
+
|
|
10
|
+
// Core
|
|
11
|
+
import cli from '@cli';
|
|
12
|
+
import App, { TAppSide } from '../../../../app';
|
|
13
|
+
|
|
14
|
+
/*----------------------------------
|
|
15
|
+
- WEBPACK RULE
|
|
16
|
+
----------------------------------*/
|
|
17
|
+
|
|
18
|
+
type TOptions = {
|
|
19
|
+
side: TAppSide,
|
|
20
|
+
app: App
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
module.exports = (options: TOptions) => (
|
|
24
|
+
[Plugin, options]
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
const debug = true;
|
|
28
|
+
|
|
29
|
+
/*----------------------------------
|
|
30
|
+
- PLUGIN
|
|
31
|
+
----------------------------------*/
|
|
32
|
+
function Plugin(babel, { app, side }: TOptions) {
|
|
33
|
+
|
|
34
|
+
const t = babel.types as typeof types;
|
|
35
|
+
|
|
36
|
+
/*
|
|
37
|
+
- Wrap route.get(...) with (app: Application) => { }
|
|
38
|
+
- Inject chunk ID into client route options
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
const plugin: PluginObj<{
|
|
42
|
+
|
|
43
|
+
filename: string,
|
|
44
|
+
fileType: 'front' | 'back',
|
|
45
|
+
processFile: boolean,
|
|
46
|
+
|
|
47
|
+
// Identifier => Name
|
|
48
|
+
importedServices: {[local: string]: string},
|
|
49
|
+
routeDefinitions: types.Expression[]
|
|
50
|
+
}> = {
|
|
51
|
+
pre(state) {
|
|
52
|
+
|
|
53
|
+
this.filename = state.opts.filename as string;
|
|
54
|
+
this.processFile = true;
|
|
55
|
+
|
|
56
|
+
if (
|
|
57
|
+
this.filename.startsWith( cli.paths.appRoot + '/src/client/pages' )
|
|
58
|
+
||
|
|
59
|
+
this.filename.startsWith( cli.paths.coreRoot + '/src/client/pages' )
|
|
60
|
+
) {
|
|
61
|
+
|
|
62
|
+
this.fileType = 'front';
|
|
63
|
+
|
|
64
|
+
} else if (this.filename.startsWith( cli.paths.appRoot + '/src/server/routes' )) {
|
|
65
|
+
|
|
66
|
+
this.fileType = 'back';
|
|
67
|
+
|
|
68
|
+
} else
|
|
69
|
+
this.processFile = false;
|
|
70
|
+
|
|
71
|
+
this.importedServices = {}
|
|
72
|
+
this.routeDefinitions = []
|
|
73
|
+
|
|
74
|
+
},
|
|
75
|
+
visitor: {
|
|
76
|
+
|
|
77
|
+
// Find @app imports
|
|
78
|
+
// Test: import { router } from '@app';
|
|
79
|
+
// Replace by: nothing
|
|
80
|
+
ImportDeclaration(path) {
|
|
81
|
+
|
|
82
|
+
if (!this.processFile)
|
|
83
|
+
return;
|
|
84
|
+
|
|
85
|
+
if (path.node.source.value !== '@app')
|
|
86
|
+
return;
|
|
87
|
+
|
|
88
|
+
for (const specifier of path.node.specifiers) {
|
|
89
|
+
|
|
90
|
+
if (specifier.type !== 'ImportSpecifier')
|
|
91
|
+
continue;
|
|
92
|
+
|
|
93
|
+
if (specifier.imported.type !== 'Identifier')
|
|
94
|
+
continue;
|
|
95
|
+
|
|
96
|
+
this.importedServices[ specifier.local.name ] = specifier.imported.name;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Remove this import
|
|
100
|
+
path.replaceWithMultiple([]);
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
// Find router definitions
|
|
104
|
+
// Test: router.xxx()
|
|
105
|
+
// Replace by: nothing
|
|
106
|
+
CallExpression(path) {
|
|
107
|
+
|
|
108
|
+
if (!this.processFile)
|
|
109
|
+
return;
|
|
110
|
+
|
|
111
|
+
// Should be at the root of the document
|
|
112
|
+
if (!(
|
|
113
|
+
path.parent.type === 'ExpressionStatement'
|
|
114
|
+
&&
|
|
115
|
+
path.parentPath.parent.type === 'Program'
|
|
116
|
+
))
|
|
117
|
+
return;
|
|
118
|
+
|
|
119
|
+
// service.method()
|
|
120
|
+
const callee = path.node.callee
|
|
121
|
+
if (!(
|
|
122
|
+
callee.type === 'MemberExpression'
|
|
123
|
+
&&
|
|
124
|
+
callee.object.type === 'Identifier'
|
|
125
|
+
&&
|
|
126
|
+
callee.property.type === 'Identifier'
|
|
127
|
+
&&
|
|
128
|
+
(callee.object.name in this.importedServices)
|
|
129
|
+
))
|
|
130
|
+
return;
|
|
131
|
+
|
|
132
|
+
// Client route definition: Add chunk id
|
|
133
|
+
let [routePath, ...routeArgs] = path.node.arguments;
|
|
134
|
+
if (this.fileType === 'front' && callee.object.name === 'router') {
|
|
135
|
+
|
|
136
|
+
// Inject chunk id in options (2nd arg)
|
|
137
|
+
const newRouteArgs = injectChunkId(routeArgs, this.filename);
|
|
138
|
+
if (newRouteArgs === 'ALREADY_PROCESSED')
|
|
139
|
+
return;
|
|
140
|
+
|
|
141
|
+
routeArgs = newRouteArgs;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Force babel to create new fresh nodes
|
|
145
|
+
// If we directy use statementParent, it will not be included in the final compiler code
|
|
146
|
+
const statementParent =
|
|
147
|
+
t.callExpression(
|
|
148
|
+
t.memberExpression(
|
|
149
|
+
t.identifier( callee.object.name ),
|
|
150
|
+
callee.property,
|
|
151
|
+
),
|
|
152
|
+
[routePath, ...routeArgs]
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
this.routeDefinitions.push( statementParent );
|
|
156
|
+
|
|
157
|
+
// Delete this node
|
|
158
|
+
path.replaceWithMultiple([]);
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
// Wrap declarations into a exported const app function
|
|
162
|
+
/*
|
|
163
|
+
export const __register = ({ router }} => {
|
|
164
|
+
|
|
165
|
+
router.page(..)
|
|
166
|
+
|
|
167
|
+
}
|
|
168
|
+
*/
|
|
169
|
+
Program: {
|
|
170
|
+
exit: function(path, parent) {
|
|
171
|
+
|
|
172
|
+
const importedServices = Object.entries(this.importedServices);
|
|
173
|
+
if (importedServices.length === 0)
|
|
174
|
+
return;
|
|
175
|
+
|
|
176
|
+
let exportValue: types.Expression | types.BlockStatement;
|
|
177
|
+
if (this.fileType === 'front') {
|
|
178
|
+
|
|
179
|
+
const routesDefCount = this.routeDefinitions.length;
|
|
180
|
+
if (routesDefCount !== 1)
|
|
181
|
+
throw new Error(`Frontend route definition files (/client/pages/**/**.ts) can contain only one route definition.
|
|
182
|
+
${routesDefCount} were given in ${this.filename}.`);
|
|
183
|
+
|
|
184
|
+
exportValue = this.routeDefinitions[0];
|
|
185
|
+
|
|
186
|
+
} else {
|
|
187
|
+
|
|
188
|
+
exportValue = t.blockStatement([
|
|
189
|
+
// Without spread = react jxx need additionnal loader
|
|
190
|
+
...this.routeDefinitions.map( def =>
|
|
191
|
+
t.expressionStatement(def)
|
|
192
|
+
),
|
|
193
|
+
])
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const exportDeclaration = t.exportNamedDeclaration(
|
|
197
|
+
t.variableDeclaration('const', [
|
|
198
|
+
t.variableDeclarator(
|
|
199
|
+
t.identifier('__register'),
|
|
200
|
+
t.arrowFunctionExpression(
|
|
201
|
+
[
|
|
202
|
+
t.objectPattern(
|
|
203
|
+
importedServices.map(([ local, imported ]) =>
|
|
204
|
+
t.objectProperty(
|
|
205
|
+
t.identifier( local ),
|
|
206
|
+
t.identifier( imported ),
|
|
207
|
+
)
|
|
208
|
+
)
|
|
209
|
+
)
|
|
210
|
+
],
|
|
211
|
+
exportValue
|
|
212
|
+
)
|
|
213
|
+
)
|
|
214
|
+
])
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
// Sans
|
|
218
|
+
// console.log('import app via', this.filename, this.importedServices);
|
|
219
|
+
//debug && console.log( generate(exportDeclaration).code )
|
|
220
|
+
path.pushContainer('body', [exportDeclaration])
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function injectChunkId(
|
|
227
|
+
routeArgs: types.CallExpression["arguments"],
|
|
228
|
+
filename: string
|
|
229
|
+
): types.CallExpression["arguments"] | 'ALREADY_PROCESSED' {
|
|
230
|
+
|
|
231
|
+
let [routeOptions, ...otherArgs] = routeArgs;
|
|
232
|
+
|
|
233
|
+
const { filepath, chunkId } = cli.paths.getPageChunk(app, filename);
|
|
234
|
+
debug && console.log(`[routes]`, filename, '=>', chunkId);
|
|
235
|
+
|
|
236
|
+
const newProperties = [
|
|
237
|
+
t.objectProperty(
|
|
238
|
+
t.identifier('id'),
|
|
239
|
+
t.stringLiteral(chunkId)
|
|
240
|
+
),
|
|
241
|
+
t.objectProperty(
|
|
242
|
+
t.identifier('filepath'),
|
|
243
|
+
t.stringLiteral(filepath)
|
|
244
|
+
)
|
|
245
|
+
]
|
|
246
|
+
|
|
247
|
+
// No options object
|
|
248
|
+
if (routeOptions.type !== 'ObjectExpression') {
|
|
249
|
+
return [
|
|
250
|
+
t.objectExpression(newProperties),
|
|
251
|
+
...routeArgs
|
|
252
|
+
]
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const wasAlreadyProcessed = routeOptions.properties.some( o =>
|
|
256
|
+
o.type === 'ObjectProperty'
|
|
257
|
+
&&
|
|
258
|
+
o.key.type === 'Identifier'
|
|
259
|
+
&&
|
|
260
|
+
o.key.name === 'id'
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
if (wasAlreadyProcessed) {
|
|
264
|
+
// Cancel processing
|
|
265
|
+
debug && console.log(`[routes]`, filename, 'Already Processed');
|
|
266
|
+
return 'ALREADY_PROCESSED';
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return [
|
|
270
|
+
t.objectExpression([
|
|
271
|
+
...routeOptions.properties,
|
|
272
|
+
...newProperties
|
|
273
|
+
]),
|
|
274
|
+
...otherArgs
|
|
275
|
+
]
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return plugin;
|
|
279
|
+
}
|
|
@@ -80,57 +80,22 @@ function Plugin(babel, { side }: TOptions) {
|
|
|
80
80
|
const replacement = t.callExpression( path.node.callee, [ routePath, ...routeArgs ]);
|
|
81
81
|
debug && console.log( generate(replacement).code );
|
|
82
82
|
|
|
83
|
+
path.replaceWith( replacement );
|
|
84
|
+
|
|
83
85
|
// Force export default
|
|
84
|
-
|
|
86
|
+
// NOTE: now done by app-import.ts
|
|
87
|
+
/*if (path.parent.type === 'ExportDefaultDeclaration')
|
|
85
88
|
path.replaceWith( replacement );
|
|
86
89
|
else
|
|
87
90
|
path.parentPath.replaceWith(
|
|
88
91
|
t.exportDefaultDeclaration( replacement )
|
|
89
|
-
)
|
|
92
|
+
)*/
|
|
90
93
|
|
|
91
94
|
}
|
|
92
95
|
|
|
93
96
|
}
|
|
94
97
|
};
|
|
95
98
|
|
|
96
|
-
function addChunkId(
|
|
97
|
-
routeArgs: types.CallExpression["arguments"],
|
|
98
|
-
filename: string
|
|
99
|
-
): void | 'ALREADY_PROCESSED' {
|
|
100
|
-
|
|
101
|
-
if (routeArgs[0].type === 'ObjectExpression') {
|
|
102
|
-
|
|
103
|
-
if (routeArgs[0].properties.some(o =>
|
|
104
|
-
o.type === 'ObjectProperty'
|
|
105
|
-
&&
|
|
106
|
-
o.key.type === 'Identifier'
|
|
107
|
-
&&
|
|
108
|
-
o.key.name === 'id'
|
|
109
|
-
)) {
|
|
110
|
-
debug && console.log(`[routes]`, filename, 'Already Processed');
|
|
111
|
-
return 'ALREADY_PROCESSED';
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
} else
|
|
115
|
-
routeArgs.unshift(t.objectExpression([]));
|
|
116
|
-
|
|
117
|
-
const { filepath, chunkId } = cli.paths.getPageChunk(app, filename);
|
|
118
|
-
debug && console.log(`[routes]`, filename, '=>', chunkId);
|
|
119
|
-
|
|
120
|
-
// Add object property
|
|
121
|
-
(routeArgs[0] as types.ObjectExpression).properties.push(
|
|
122
|
-
t.objectProperty(
|
|
123
|
-
t.identifier('id'),
|
|
124
|
-
t.stringLiteral(chunkId)
|
|
125
|
-
),
|
|
126
|
-
t.objectProperty(
|
|
127
|
-
t.identifier('filepath'),
|
|
128
|
-
t.stringLiteral(filepath)
|
|
129
|
-
)
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
|
|
134
99
|
function addRendererContext(
|
|
135
100
|
routeArgs: types.CallExpression["arguments"],
|
|
136
101
|
filename: string
|
|
@@ -175,7 +140,7 @@ function Plugin(babel, { side }: TOptions) {
|
|
|
175
140
|
'body',
|
|
176
141
|
t.importDeclaration(
|
|
177
142
|
[t.importDefaultSpecifier(t.identifier('useContext'))],
|
|
178
|
-
t.stringLiteral('
|
|
143
|
+
t.stringLiteral('@/client/context')
|
|
179
144
|
)
|
|
180
145
|
);
|
|
181
146
|
}
|
|
@@ -20,7 +20,7 @@ export const fixNpmLinkIssues = ( app: App ) => {
|
|
|
20
20
|
|
|
21
21
|
const corePath = path.join(app.paths.root, '/node_modules/5htp-core');
|
|
22
22
|
if (!fs.lstatSync( corePath ).isSymbolicLink())
|
|
23
|
-
return;
|
|
23
|
+
return console.info("Not fixing npm issue because 5htp-core wasn't installed with npm link.");
|
|
24
24
|
|
|
25
25
|
console.info(`Fix NPM link issues ...`);
|
|
26
26
|
|
|
@@ -42,5 +42,5 @@ export const fixNpmLinkIssues = ( app: App ) => {
|
|
|
42
42
|
if (!fs.existsSync( preactAppModule ))
|
|
43
43
|
fs.symlinkSync( preactCoreModule, preactAppModule );
|
|
44
44
|
if (!fs.existsSync( reactAppModule ))
|
|
45
|
-
fs.symlinkSync( preactCoreModule, reactAppModule );
|
|
45
|
+
fs.symlinkSync( path.join(preactCoreModule, 'compat'), reactAppModule );
|
|
46
46
|
}
|
package/src/compiler/index.ts
CHANGED
|
@@ -101,6 +101,12 @@ export default async function createCompilers(
|
|
|
101
101
|
const time = timeEnd.getTime() - timeStart.getTime();
|
|
102
102
|
if (stats.hasErrors()) {
|
|
103
103
|
console.error(`############## Failed to compile '${name}' after ${time} ms`);
|
|
104
|
+
|
|
105
|
+
// Exit process with code 0, so the CI container can understand building failed
|
|
106
|
+
// Only in prod, because in dev, we want the compiler watcher continue running
|
|
107
|
+
if (mode === 'prod')
|
|
108
|
+
process.exit(0);
|
|
109
|
+
|
|
104
110
|
} else {
|
|
105
111
|
console.info(`############## [${name}] Finished compilation after ${time} ms`);
|
|
106
112
|
}
|
|
@@ -43,11 +43,16 @@ export default function createCompiler( app: App, mode: TCompileMode ): webpack.
|
|
|
43
43
|
const dev = mode === 'dev';
|
|
44
44
|
|
|
45
45
|
const commonConfig = createCommonConfig(app, 'server', mode);
|
|
46
|
-
const { aliases } = app.aliases.server.forWebpack(
|
|
46
|
+
const { aliases } = app.aliases.server.forWebpack({
|
|
47
|
+
modulesPath: app.paths.root + '/node_modules'
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// We're not supposed in any case to import client services from server
|
|
51
|
+
delete aliases["@client/services"];
|
|
52
|
+
delete aliases["@/client/services"];
|
|
47
53
|
|
|
48
54
|
console.log(`[${mode}] node_modules dirs:`, commonConfig.resolveLoader?.modules,
|
|
49
|
-
'\nModule aliases:', aliases);
|
|
50
|
-
|
|
55
|
+
'\nModule aliases for webpack:', aliases);
|
|
51
56
|
const config: webpack.Configuration = {
|
|
52
57
|
|
|
53
58
|
...commonConfig,
|
|
@@ -56,7 +61,7 @@ export default function createCompiler( app: App, mode: TCompileMode ): webpack.
|
|
|
56
61
|
target: 'node',
|
|
57
62
|
entry: {
|
|
58
63
|
server: [
|
|
59
|
-
|
|
64
|
+
cli.paths.coreRoot + '/src/server/index.ts'
|
|
60
65
|
],
|
|
61
66
|
},
|
|
62
67
|
|
|
@@ -115,10 +120,7 @@ export default function createCompiler( app: App, mode: TCompileMode ): webpack.
|
|
|
115
120
|
|
|
116
121
|
...commonConfig.resolve,
|
|
117
122
|
|
|
118
|
-
alias:
|
|
119
|
-
...aliases,
|
|
120
|
-
"@root": app.paths.root,
|
|
121
|
-
},
|
|
123
|
+
alias: aliases,
|
|
122
124
|
|
|
123
125
|
extensions: ['.ts', '.tsx', ".json", ".sql"],
|
|
124
126
|
},
|
package/src/index.ts
CHANGED
|
@@ -19,6 +19,10 @@ type TCliCommand = () => Promise<{
|
|
|
19
19
|
run: () => Promise<void>
|
|
20
20
|
}>
|
|
21
21
|
|
|
22
|
+
type TArgsObject = {
|
|
23
|
+
[key: string]: string | boolean | string[]
|
|
24
|
+
}
|
|
25
|
+
|
|
22
26
|
/*----------------------------------
|
|
23
27
|
- CLASSE
|
|
24
28
|
----------------------------------*/
|
|
@@ -28,7 +32,7 @@ type TCliCommand = () => Promise<{
|
|
|
28
32
|
export class CLI {
|
|
29
33
|
|
|
30
34
|
// Context
|
|
31
|
-
public args:
|
|
35
|
+
public args: TArgsObject = {};
|
|
32
36
|
|
|
33
37
|
public constructor(
|
|
34
38
|
public paths = new Paths( process.cwd() )
|
|
@@ -98,7 +102,7 @@ export class CLI {
|
|
|
98
102
|
this.runCommand(commandName, options);
|
|
99
103
|
}
|
|
100
104
|
|
|
101
|
-
public async runCommand(command: string, args:
|
|
105
|
+
public async runCommand(command: string, args: TArgsObject) {
|
|
102
106
|
|
|
103
107
|
this.args = args;
|
|
104
108
|
|
package/src/paths.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import path from 'path';
|
|
7
7
|
import TsAlias from 'ts-alias';
|
|
8
8
|
import moduleAlias from 'module-alias';
|
|
9
|
+
import { filenameToImportName } from 'babel-plugin-glob-import';
|
|
9
10
|
|
|
10
11
|
// Core
|
|
11
12
|
|
|
@@ -16,6 +17,13 @@ import moduleAlias from 'module-alias';
|
|
|
16
17
|
import type App from './app';
|
|
17
18
|
import type { TAppSide } from './app';
|
|
18
19
|
|
|
20
|
+
export type TPathInfosOptions = {
|
|
21
|
+
basePath?: string,
|
|
22
|
+
shortenExtensions: string[],
|
|
23
|
+
// Indexed will be trimed only when the extension can be shorten
|
|
24
|
+
trimIndex: boolean,
|
|
25
|
+
}
|
|
26
|
+
|
|
19
27
|
export type TPathInfos = {
|
|
20
28
|
|
|
21
29
|
original: string,
|
|
@@ -28,8 +36,17 @@ export type TPathInfos = {
|
|
|
28
36
|
isIndex: boolean
|
|
29
37
|
}
|
|
30
38
|
|
|
39
|
+
/*----------------------------------
|
|
40
|
+
- CONFIG
|
|
41
|
+
----------------------------------*/
|
|
42
|
+
|
|
31
43
|
export const staticAssetName = /*isDebug ? '[name].[ext].[hash:8]' :*/ '[hash:8][ext]';
|
|
32
44
|
|
|
45
|
+
const pathInfosDefaultOpts = {
|
|
46
|
+
shortenExtensions: ['ts', 'js', 'tsx', 'jsx'],
|
|
47
|
+
trimIndex: true,
|
|
48
|
+
}
|
|
49
|
+
|
|
33
50
|
/*----------------------------------
|
|
34
51
|
- LIB
|
|
35
52
|
----------------------------------*/
|
|
@@ -57,18 +74,20 @@ export default class Paths {
|
|
|
57
74
|
- EXTRACTION
|
|
58
75
|
----------------------------------*/
|
|
59
76
|
|
|
60
|
-
public infos(filename: string,
|
|
77
|
+
public infos(filename: string, givenOpts: Partial<TPathInfosOptions> = {}): TPathInfos {
|
|
78
|
+
|
|
79
|
+
const opts: TPathInfosOptions = { ...pathInfosDefaultOpts, ...givenOpts }
|
|
61
80
|
|
|
62
81
|
// Extraction élements du chemin
|
|
63
82
|
const decomp = filename.split('/')
|
|
64
83
|
let [nomFichier, extension] = (decomp.pop() as string).split('.');
|
|
65
|
-
const
|
|
84
|
+
const shortenExtension = opts.shortenExtensions && opts.shortenExtensions.includes(extension);
|
|
66
85
|
|
|
67
86
|
// Vire l'index
|
|
68
87
|
const isIndex = nomFichier === 'index'
|
|
69
88
|
let cheminAbsolu: string;
|
|
70
89
|
let nomReel: string;
|
|
71
|
-
if (isIndex &&
|
|
90
|
+
if (isIndex && shortenExtension && opts.trimIndex) {
|
|
72
91
|
cheminAbsolu = decomp.join('/');
|
|
73
92
|
nomReel = decomp.pop() as string;
|
|
74
93
|
} else {
|
|
@@ -77,12 +96,12 @@ export default class Paths {
|
|
|
77
96
|
}
|
|
78
97
|
|
|
79
98
|
// Conserve l'extension si nécessaire
|
|
80
|
-
if (!
|
|
99
|
+
if (!shortenExtension)
|
|
81
100
|
cheminAbsolu += '.' + extension;
|
|
82
101
|
|
|
83
|
-
const relative = basePath === undefined
|
|
102
|
+
const relative = opts.basePath === undefined
|
|
84
103
|
? ''
|
|
85
|
-
: cheminAbsolu.substring( basePath.length + 1 )
|
|
104
|
+
: cheminAbsolu.substring( opts.basePath.length + 1 )
|
|
86
105
|
|
|
87
106
|
// Retour
|
|
88
107
|
const retour = {
|
|
@@ -104,16 +123,17 @@ export default class Paths {
|
|
|
104
123
|
|
|
105
124
|
public getPageChunk( app: App, file: string ) {
|
|
106
125
|
|
|
107
|
-
const infos = this.infos( file,
|
|
108
|
-
? app.paths.pages
|
|
109
|
-
|
|
110
|
-
|
|
126
|
+
const infos = this.infos( file, {
|
|
127
|
+
basePath: file.startsWith( app.paths.pages ) ? app.paths.pages : this.core.pages,
|
|
128
|
+
// Avoid potential conflicts between /landing.tsx and /landing/index.tsx
|
|
129
|
+
trimIndex: false,
|
|
130
|
+
});
|
|
111
131
|
|
|
112
132
|
const filepath = infos.relative;
|
|
113
133
|
|
|
114
134
|
// Before: /home/.../src/client/pages/landing/index.tsx
|
|
115
135
|
// After: landing_index
|
|
116
|
-
let chunkId = filepath
|
|
136
|
+
let chunkId = filenameToImportName(filepath);
|
|
117
137
|
|
|
118
138
|
// nsure it's non-empty
|
|
119
139
|
if (chunkId.length === 0) // = /index.tsx
|