5htp 0.6.3 → 0.6.4
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/app/index.ts +8 -2
- package/cli.js +13 -0
- package/commands/build.ts +35 -8
- package/commands/refresh.ts +18 -0
- package/compiler/client/index.ts +5 -7
- package/compiler/common/babel/index.ts +0 -10
- package/compiler/common/babel/plugins/services.ts +263 -13
- package/compiler/common/babel/routes/routes.ts +500 -13
- package/compiler/common/index.ts +9 -13
- package/compiler/index.ts +32 -17
- package/compiler/server/index.ts +6 -3
- package/index.ts +5 -3
- package/package.json +3 -4
- package/readme.md +14 -2
- package/compiler/common/babel/plugins/form.ts +0 -191
- package/compiler/common/babel/plugins/icones-svg.ts +0 -376
- package/compiler/common/babel/plugins/injection-dependances/index.ts +0 -225
- package/compiler/common/babel/plugins/injection-dependances/remplacerFonction.ts +0 -226
- package/compiler/common/babel/plugins/queries/index.ts +0 -166
- package/compiler/common/plugins/indexage/_utils/Stringify.ts +0 -72
- package/compiler/common/plugins/indexage/_utils/annotations.ts +0 -88
- package/compiler/common/plugins/indexage/_utils/iterateur.ts +0 -52
- package/compiler/common/plugins/indexage/icones-svg/index.ts +0 -207
- package/compiler/common/plugins/indexage/index.ts +0 -134
- package/compiler/common/plugins/indexage/indexeur.ts +0 -13
- package/compiler/common/plugins/indexage/injection-dependances/index.ts +0 -68
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
// Npm
|
|
6
6
|
import * as types from '@babel/types'
|
|
7
7
|
import type { PluginObj, NodePath } from '@babel/core';
|
|
8
|
-
import generate from '@babel/generator';
|
|
9
8
|
|
|
10
9
|
// Core
|
|
11
10
|
import cli from '@cli';
|
|
@@ -53,6 +52,13 @@ function Plugin(babel, { app, side, debug }: TOptions) {
|
|
|
53
52
|
|
|
54
53
|
const t = babel.types as typeof types;
|
|
55
54
|
|
|
55
|
+
type TPluginState = {
|
|
56
|
+
filename: string,
|
|
57
|
+
file: TFileInfos,
|
|
58
|
+
apiInjectedRootFunctions: WeakSet<types.Node>,
|
|
59
|
+
needsUseContextImport: boolean
|
|
60
|
+
}
|
|
61
|
+
|
|
56
62
|
/*
|
|
57
63
|
- Wrap route.get(...) with (app: Application) => { }
|
|
58
64
|
- Inject chunk ID into client route options
|
|
@@ -70,14 +76,14 @@ function Plugin(babel, { app, side, debug }: TOptions) {
|
|
|
70
76
|
const stats = page.data.stats;
|
|
71
77
|
*/
|
|
72
78
|
|
|
73
|
-
const plugin: PluginObj<{
|
|
74
|
-
filename: string,
|
|
75
|
-
file: TFileInfos
|
|
76
|
-
}> = {
|
|
79
|
+
const plugin: PluginObj<TPluginState> = {
|
|
77
80
|
pre(state) {
|
|
78
81
|
this.filename = state.opts.filename as string;
|
|
79
82
|
|
|
80
83
|
this.file = getFileInfos(this.filename);
|
|
84
|
+
|
|
85
|
+
this.apiInjectedRootFunctions = new WeakSet();
|
|
86
|
+
this.needsUseContextImport = false;
|
|
81
87
|
},
|
|
82
88
|
visitor: {
|
|
83
89
|
// Find @app imports
|
|
@@ -184,9 +190,7 @@ function Plugin(babel, { app, side, debug }: TOptions) {
|
|
|
184
190
|
// Delete the route def since it will be replaced by a wrapper
|
|
185
191
|
path.replaceWithMultiple([]);
|
|
186
192
|
|
|
187
|
-
|
|
188
|
-
Any api call via the front pages / components
|
|
189
|
-
*/
|
|
193
|
+
|
|
190
194
|
} else if (this.file.side === 'front') {
|
|
191
195
|
|
|
192
196
|
const isAService = (
|
|
@@ -201,10 +205,12 @@ function Plugin(babel, { app, side, debug }: TOptions) {
|
|
|
201
205
|
|
|
202
206
|
Events.Create( form.data ).then(res => toast.success(res.message))
|
|
203
207
|
=>
|
|
204
|
-
api.post( '/api/events/create', form.data ).then(res => toast.success(res.message))
|
|
208
|
+
api.post( '/api/events/create', form.data ).then(res => toast.success(res.message)).catch(app.handleError)
|
|
205
209
|
*/
|
|
206
210
|
if (side === 'client' && !clientServices.includes(serviceName)) {
|
|
207
211
|
|
|
212
|
+
ensureApiExposedInRootFunction(path, this);
|
|
213
|
+
|
|
208
214
|
// Get complete call path
|
|
209
215
|
const apiPath = '/api/' + completePath.join('/');
|
|
210
216
|
|
|
@@ -220,6 +226,8 @@ function Plugin(babel, { app, side, debug }: TOptions) {
|
|
|
220
226
|
), apiPostArgs
|
|
221
227
|
)
|
|
222
228
|
)
|
|
229
|
+
|
|
230
|
+
ensureBackendServicePromiseCatch(path);
|
|
223
231
|
|
|
224
232
|
/* [server] Backend Service calls
|
|
225
233
|
|
|
@@ -257,6 +265,8 @@ function Plugin(babel, { app, side, debug }: TOptions) {
|
|
|
257
265
|
|
|
258
266
|
if (!this.file.process)
|
|
259
267
|
return;
|
|
268
|
+
|
|
269
|
+
ensureUseContextImport(path, this);
|
|
260
270
|
|
|
261
271
|
const wrappedrouteDefs = wrapRouteDefs( this.file );
|
|
262
272
|
if (wrappedrouteDefs)
|
|
@@ -266,6 +276,485 @@ function Plugin(babel, { app, side, debug }: TOptions) {
|
|
|
266
276
|
}
|
|
267
277
|
}
|
|
268
278
|
|
|
279
|
+
function ensureBackendServicePromiseCatch(path: NodePath<types.CallExpression>) {
|
|
280
|
+
|
|
281
|
+
const chainRoot = getPromiseChainRoot(path);
|
|
282
|
+
|
|
283
|
+
// Only append if we are in a promise chain (e.g. .then(...))
|
|
284
|
+
if (chainRoot === path)
|
|
285
|
+
return;
|
|
286
|
+
|
|
287
|
+
if (isCatchWithAppHandleErrorArrow(chainRoot))
|
|
288
|
+
return;
|
|
289
|
+
|
|
290
|
+
if (isCatchWithAppHandleErrorMember(chainRoot)) {
|
|
291
|
+
const updatedCatch = t.callExpression(
|
|
292
|
+
chainRoot.node.callee,
|
|
293
|
+
[buildCatchHandler()]
|
|
294
|
+
);
|
|
295
|
+
chainRoot.replaceWith(updatedCatch);
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
if (isCatchWithAppHandleErrorWrapped(chainRoot)) {
|
|
300
|
+
const updatedCatch = t.callExpression(
|
|
301
|
+
chainRoot.node.callee,
|
|
302
|
+
[buildCatchHandler()]
|
|
303
|
+
);
|
|
304
|
+
chainRoot.replaceWith(updatedCatch);
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const newChain = t.callExpression(
|
|
309
|
+
t.memberExpression(chainRoot.node, t.identifier('catch')),
|
|
310
|
+
[buildCatchHandler()]
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
chainRoot.replaceWith(newChain);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function buildCatchHandler(): types.ArrowFunctionExpression {
|
|
317
|
+
const errorIdentifier = t.identifier('e');
|
|
318
|
+
return t.arrowFunctionExpression(
|
|
319
|
+
[errorIdentifier],
|
|
320
|
+
t.callExpression(
|
|
321
|
+
t.memberExpression(t.identifier('app'), t.identifier('handleError')),
|
|
322
|
+
[t.identifier(errorIdentifier.name)]
|
|
323
|
+
)
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function getPromiseChainRoot(path: NodePath<types.CallExpression>): NodePath<types.CallExpression> {
|
|
328
|
+
|
|
329
|
+
let current = path;
|
|
330
|
+
|
|
331
|
+
while (1) {
|
|
332
|
+
|
|
333
|
+
const member = current.parentPath;
|
|
334
|
+
if (!member?.isMemberExpression())
|
|
335
|
+
break;
|
|
336
|
+
|
|
337
|
+
if (member.node.object !== current.node)
|
|
338
|
+
break;
|
|
339
|
+
|
|
340
|
+
if (member.node.property.type !== 'Identifier')
|
|
341
|
+
break;
|
|
342
|
+
|
|
343
|
+
const propName = member.node.property.name;
|
|
344
|
+
if (!['then', 'catch', 'finally'].includes(propName))
|
|
345
|
+
break;
|
|
346
|
+
|
|
347
|
+
const call = member.parentPath;
|
|
348
|
+
if (!call?.isCallExpression())
|
|
349
|
+
break;
|
|
350
|
+
|
|
351
|
+
if (call.node.callee !== member.node)
|
|
352
|
+
break;
|
|
353
|
+
|
|
354
|
+
current = call;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return current;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
function isCatchCall(path: NodePath<types.CallExpression>): boolean {
|
|
361
|
+
|
|
362
|
+
const callee = path.node.callee;
|
|
363
|
+
if (callee.type !== 'MemberExpression')
|
|
364
|
+
return false;
|
|
365
|
+
|
|
366
|
+
if (callee.property.type !== 'Identifier' || callee.property.name !== 'catch')
|
|
367
|
+
return false;
|
|
368
|
+
|
|
369
|
+
return true;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function isCatchWithAppHandleErrorMember(path: NodePath<types.CallExpression>): boolean {
|
|
373
|
+
|
|
374
|
+
if (!isCatchCall(path))
|
|
375
|
+
return false;
|
|
376
|
+
|
|
377
|
+
if (path.node.arguments.length !== 1)
|
|
378
|
+
return false;
|
|
379
|
+
|
|
380
|
+
const handler = path.node.arguments[0];
|
|
381
|
+
if (handler.type !== 'MemberExpression')
|
|
382
|
+
return false;
|
|
383
|
+
|
|
384
|
+
if (handler.object.type !== 'Identifier' || handler.object.name !== 'app')
|
|
385
|
+
return false;
|
|
386
|
+
|
|
387
|
+
if (handler.property.type !== 'Identifier' || handler.property.name !== 'handleError')
|
|
388
|
+
return false;
|
|
389
|
+
|
|
390
|
+
return true;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
function isCatchWithAppHandleErrorArrow(path: NodePath<types.CallExpression>): boolean {
|
|
394
|
+
|
|
395
|
+
if (!isCatchCall(path))
|
|
396
|
+
return false;
|
|
397
|
+
|
|
398
|
+
if (path.node.arguments.length !== 1)
|
|
399
|
+
return false;
|
|
400
|
+
|
|
401
|
+
const handler = path.node.arguments[0];
|
|
402
|
+
if (handler.type !== 'ArrowFunctionExpression')
|
|
403
|
+
return false;
|
|
404
|
+
|
|
405
|
+
if (
|
|
406
|
+
handler.params.length !== 1
|
|
407
|
+
||
|
|
408
|
+
handler.params[0].type !== 'Identifier'
|
|
409
|
+
)
|
|
410
|
+
return false;
|
|
411
|
+
|
|
412
|
+
const errorName = handler.params[0].name;
|
|
413
|
+
|
|
414
|
+
if (handler.body.type !== 'CallExpression')
|
|
415
|
+
return false;
|
|
416
|
+
|
|
417
|
+
const call = handler.body;
|
|
418
|
+
if (call.callee.type !== 'MemberExpression')
|
|
419
|
+
return false;
|
|
420
|
+
|
|
421
|
+
if (call.callee.object.type !== 'Identifier' || call.callee.object.name !== 'app')
|
|
422
|
+
return false;
|
|
423
|
+
|
|
424
|
+
if (call.callee.property.type !== 'Identifier' || call.callee.property.name !== 'handleError')
|
|
425
|
+
return false;
|
|
426
|
+
|
|
427
|
+
if (call.arguments.length !== 1)
|
|
428
|
+
return false;
|
|
429
|
+
|
|
430
|
+
const arg = call.arguments[0];
|
|
431
|
+
if (arg.type !== 'Identifier' || arg.name !== errorName)
|
|
432
|
+
return false;
|
|
433
|
+
|
|
434
|
+
return true;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
function isCatchWithAppHandleErrorWrapped(path: NodePath<types.CallExpression>): boolean {
|
|
438
|
+
|
|
439
|
+
if (!isCatchCall(path))
|
|
440
|
+
return false;
|
|
441
|
+
|
|
442
|
+
if (path.node.arguments.length !== 1)
|
|
443
|
+
return false;
|
|
444
|
+
|
|
445
|
+
const handler = path.node.arguments[0];
|
|
446
|
+
if (handler.type !== 'ArrowFunctionExpression')
|
|
447
|
+
return false;
|
|
448
|
+
|
|
449
|
+
if (
|
|
450
|
+
handler.params.length !== 1
|
|
451
|
+
||
|
|
452
|
+
handler.params[0].type !== 'Identifier'
|
|
453
|
+
)
|
|
454
|
+
return false;
|
|
455
|
+
|
|
456
|
+
const errorName = handler.params[0].name;
|
|
457
|
+
|
|
458
|
+
if (handler.body.type !== 'BlockStatement')
|
|
459
|
+
return false;
|
|
460
|
+
|
|
461
|
+
const statements = handler.body.body;
|
|
462
|
+
if (statements.length < 2)
|
|
463
|
+
return false;
|
|
464
|
+
|
|
465
|
+
const first = statements[0];
|
|
466
|
+
if (!(
|
|
467
|
+
first.type === 'ExpressionStatement'
|
|
468
|
+
&&
|
|
469
|
+
first.expression.type === 'CallExpression'
|
|
470
|
+
&&
|
|
471
|
+
first.expression.callee.type === 'MemberExpression'
|
|
472
|
+
&&
|
|
473
|
+
first.expression.callee.object.type === 'Identifier'
|
|
474
|
+
&&
|
|
475
|
+
first.expression.callee.object.name === 'console'
|
|
476
|
+
&&
|
|
477
|
+
first.expression.callee.property.type === 'Identifier'
|
|
478
|
+
&&
|
|
479
|
+
first.expression.callee.property.name === 'log'
|
|
480
|
+
&&
|
|
481
|
+
first.expression.arguments.length === 2
|
|
482
|
+
&&
|
|
483
|
+
first.expression.arguments[0].type === 'StringLiteral'
|
|
484
|
+
&&
|
|
485
|
+
first.expression.arguments[0].value === 'Error catched'
|
|
486
|
+
&&
|
|
487
|
+
first.expression.arguments[1].type === 'Identifier'
|
|
488
|
+
&&
|
|
489
|
+
first.expression.arguments[1].name === errorName
|
|
490
|
+
))
|
|
491
|
+
return false;
|
|
492
|
+
|
|
493
|
+
const second = statements[1];
|
|
494
|
+
if (!(
|
|
495
|
+
second.type === 'ExpressionStatement'
|
|
496
|
+
&&
|
|
497
|
+
second.expression.type === 'CallExpression'
|
|
498
|
+
&&
|
|
499
|
+
second.expression.callee.type === 'MemberExpression'
|
|
500
|
+
&&
|
|
501
|
+
second.expression.callee.object.type === 'Identifier'
|
|
502
|
+
&&
|
|
503
|
+
second.expression.callee.object.name === 'app'
|
|
504
|
+
&&
|
|
505
|
+
second.expression.callee.property.type === 'Identifier'
|
|
506
|
+
&&
|
|
507
|
+
second.expression.callee.property.name === 'handleError'
|
|
508
|
+
&&
|
|
509
|
+
second.expression.arguments.length === 1
|
|
510
|
+
&&
|
|
511
|
+
second.expression.arguments[0].type === 'Identifier'
|
|
512
|
+
&&
|
|
513
|
+
second.expression.arguments[0].name === errorName
|
|
514
|
+
))
|
|
515
|
+
return false;
|
|
516
|
+
|
|
517
|
+
return true;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
function ensureApiExposedInRootFunction(
|
|
521
|
+
path: NodePath<types.CallExpression>,
|
|
522
|
+
pluginState: TPluginState
|
|
523
|
+
) {
|
|
524
|
+
const needsApi = !path.scope.hasBinding('api');
|
|
525
|
+
const needsApp = !path.scope.hasBinding('app');
|
|
526
|
+
if (!needsApi && !needsApp)
|
|
527
|
+
return;
|
|
528
|
+
|
|
529
|
+
const rootFunctionPath = getRootFunctionPath(path);
|
|
530
|
+
if (!rootFunctionPath)
|
|
531
|
+
return;
|
|
532
|
+
|
|
533
|
+
// Root function should be at the program body level (not nested in another function / expression)
|
|
534
|
+
if (rootFunctionPath.getFunctionParent())
|
|
535
|
+
return;
|
|
536
|
+
if (!isProgramBodyLevelFunction(rootFunctionPath))
|
|
537
|
+
return;
|
|
538
|
+
|
|
539
|
+
const existingContextObjectPattern = findUseContextDestructuringObjectPattern(rootFunctionPath);
|
|
540
|
+
if (existingContextObjectPattern) {
|
|
541
|
+
|
|
542
|
+
const existingKeys = new Set(
|
|
543
|
+
existingContextObjectPattern.properties
|
|
544
|
+
.filter((p): p is types.ObjectProperty =>
|
|
545
|
+
p.type === 'ObjectProperty'
|
|
546
|
+
&& p.key.type === 'Identifier'
|
|
547
|
+
)
|
|
548
|
+
.map(p => (p.key as types.Identifier).name)
|
|
549
|
+
);
|
|
550
|
+
|
|
551
|
+
if (needsApi && !existingKeys.has('api')) {
|
|
552
|
+
existingContextObjectPattern.properties.push(
|
|
553
|
+
t.objectProperty(t.identifier('api'), t.identifier('api'), false, true),
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
if (needsApp && !existingKeys.has('app')) {
|
|
558
|
+
existingContextObjectPattern.properties.push(
|
|
559
|
+
t.objectProperty(t.identifier('app'), t.identifier('app'), false, true),
|
|
560
|
+
);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
pluginState.needsUseContextImport = true;
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
if (pluginState.apiInjectedRootFunctions.has(rootFunctionPath.node))
|
|
568
|
+
return;
|
|
569
|
+
|
|
570
|
+
const exposeApiDeclaration = t.variableDeclaration('const', [
|
|
571
|
+
t.variableDeclarator(
|
|
572
|
+
t.objectPattern([
|
|
573
|
+
...(needsApi ? [t.objectProperty(t.identifier('api'), t.identifier('api'), false, true)] : []),
|
|
574
|
+
...(needsApp ? [t.objectProperty(t.identifier('app'), t.identifier('app'), false, true)] : []),
|
|
575
|
+
]),
|
|
576
|
+
t.callExpression(t.identifier('useContext'), [])
|
|
577
|
+
)
|
|
578
|
+
]);
|
|
579
|
+
|
|
580
|
+
const body = rootFunctionPath.node.body;
|
|
581
|
+
if (body.type === 'BlockStatement') {
|
|
582
|
+
body.body.unshift(exposeApiDeclaration);
|
|
583
|
+
} else {
|
|
584
|
+
rootFunctionPath.node.body = t.blockStatement([
|
|
585
|
+
exposeApiDeclaration,
|
|
586
|
+
t.returnStatement(body)
|
|
587
|
+
]);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
pluginState.apiInjectedRootFunctions.add(rootFunctionPath.node);
|
|
591
|
+
pluginState.needsUseContextImport = true;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
function findUseContextDestructuringObjectPattern(
|
|
595
|
+
rootFunctionPath: NodePath<types.Function | types.ArrowFunctionExpression>
|
|
596
|
+
): types.ObjectPattern | undefined {
|
|
597
|
+
|
|
598
|
+
const body = rootFunctionPath.node.body;
|
|
599
|
+
if (body.type !== 'BlockStatement')
|
|
600
|
+
return;
|
|
601
|
+
|
|
602
|
+
for (const stmt of body.body) {
|
|
603
|
+
if (stmt.type !== 'VariableDeclaration' || stmt.kind !== 'const')
|
|
604
|
+
continue;
|
|
605
|
+
|
|
606
|
+
for (const declarator of stmt.declarations) {
|
|
607
|
+
if (declarator.id.type !== 'ObjectPattern')
|
|
608
|
+
continue;
|
|
609
|
+
if (!declarator.init || declarator.init.type !== 'CallExpression')
|
|
610
|
+
continue;
|
|
611
|
+
if (declarator.init.callee.type !== 'Identifier' || declarator.init.callee.name !== 'useContext')
|
|
612
|
+
continue;
|
|
613
|
+
if (declarator.init.arguments.length !== 0)
|
|
614
|
+
continue;
|
|
615
|
+
return declarator.id;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
function getRootFunctionPath(path: NodePath): NodePath<types.Function | types.ArrowFunctionExpression> | undefined {
|
|
621
|
+
|
|
622
|
+
let functionPath = path.getFunctionParent();
|
|
623
|
+
if (!functionPath)
|
|
624
|
+
return;
|
|
625
|
+
|
|
626
|
+
// Only support plain functions / arrow functions (no class/object methods)
|
|
627
|
+
if (!(
|
|
628
|
+
functionPath.isFunctionDeclaration()
|
|
629
|
+
|| functionPath.isFunctionExpression()
|
|
630
|
+
|| functionPath.isArrowFunctionExpression()
|
|
631
|
+
))
|
|
632
|
+
return;
|
|
633
|
+
|
|
634
|
+
let parentFunction = functionPath.getFunctionParent();
|
|
635
|
+
while (parentFunction) {
|
|
636
|
+
|
|
637
|
+
if (!(
|
|
638
|
+
parentFunction.isFunctionDeclaration()
|
|
639
|
+
|| parentFunction.isFunctionExpression()
|
|
640
|
+
|| parentFunction.isArrowFunctionExpression()
|
|
641
|
+
))
|
|
642
|
+
break;
|
|
643
|
+
|
|
644
|
+
functionPath = parentFunction;
|
|
645
|
+
parentFunction = functionPath.getFunctionParent();
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
return functionPath;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
function isProgramBodyLevelFunction(path: NodePath): boolean {
|
|
652
|
+
|
|
653
|
+
const parent = path.parentPath;
|
|
654
|
+
if (!parent)
|
|
655
|
+
return false;
|
|
656
|
+
|
|
657
|
+
// function Foo() {}
|
|
658
|
+
if (parent.isProgram())
|
|
659
|
+
return true;
|
|
660
|
+
|
|
661
|
+
// export default function Foo() {} / export default () => {}
|
|
662
|
+
if (
|
|
663
|
+
parent.isExportDefaultDeclaration()
|
|
664
|
+
&&
|
|
665
|
+
parent.parentPath?.isProgram()
|
|
666
|
+
)
|
|
667
|
+
return true;
|
|
668
|
+
|
|
669
|
+
// export const Foo = () => {}
|
|
670
|
+
if (
|
|
671
|
+
parent.isExportNamedDeclaration()
|
|
672
|
+
&&
|
|
673
|
+
parent.parentPath?.isProgram()
|
|
674
|
+
)
|
|
675
|
+
return true;
|
|
676
|
+
|
|
677
|
+
// const Foo = () => {} (top-level) / export const Foo = () => {}
|
|
678
|
+
if (parent.isVariableDeclarator()) {
|
|
679
|
+
|
|
680
|
+
const declaration = parent.parentPath;
|
|
681
|
+
if (!declaration?.isVariableDeclaration())
|
|
682
|
+
return false;
|
|
683
|
+
|
|
684
|
+
const declarationParent = declaration.parentPath;
|
|
685
|
+
if (!declarationParent)
|
|
686
|
+
return false;
|
|
687
|
+
|
|
688
|
+
if (declarationParent.isProgram())
|
|
689
|
+
return true;
|
|
690
|
+
|
|
691
|
+
if (
|
|
692
|
+
declarationParent.isExportNamedDeclaration()
|
|
693
|
+
&&
|
|
694
|
+
declarationParent.parentPath?.isProgram()
|
|
695
|
+
)
|
|
696
|
+
return true;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
return false;
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
function ensureUseContextImport(path: NodePath<types.Program>, pluginState: TPluginState) {
|
|
703
|
+
|
|
704
|
+
if (!pluginState.needsUseContextImport)
|
|
705
|
+
return;
|
|
706
|
+
|
|
707
|
+
const body = path.node.body;
|
|
708
|
+
|
|
709
|
+
// Already imported as a value import
|
|
710
|
+
for (const stmt of body) {
|
|
711
|
+
if (
|
|
712
|
+
stmt.type === 'ImportDeclaration'
|
|
713
|
+
&&
|
|
714
|
+
stmt.source.value === '@/client/context'
|
|
715
|
+
&&
|
|
716
|
+
stmt.importKind !== 'type'
|
|
717
|
+
&&
|
|
718
|
+
stmt.specifiers.some(s =>
|
|
719
|
+
s.type === 'ImportDefaultSpecifier' && s.local.name === 'useContext'
|
|
720
|
+
)
|
|
721
|
+
)
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// Try to reuse an existing value import from the same module
|
|
726
|
+
for (const stmt of body) {
|
|
727
|
+
if (
|
|
728
|
+
stmt.type !== 'ImportDeclaration'
|
|
729
|
+
||
|
|
730
|
+
stmt.source.value !== '@/client/context'
|
|
731
|
+
||
|
|
732
|
+
stmt.importKind === 'type'
|
|
733
|
+
)
|
|
734
|
+
continue;
|
|
735
|
+
|
|
736
|
+
const hasDefaultImport = stmt.specifiers.some(s => s.type === 'ImportDefaultSpecifier');
|
|
737
|
+
if (!hasDefaultImport) {
|
|
738
|
+
stmt.specifiers.unshift(
|
|
739
|
+
t.importDefaultSpecifier(t.identifier('useContext'))
|
|
740
|
+
);
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
// Otherwise, add a new import (placed after existing imports)
|
|
746
|
+
const importDeclaration = t.importDeclaration(
|
|
747
|
+
[t.importDefaultSpecifier(t.identifier('useContext'))],
|
|
748
|
+
t.stringLiteral('@/client/context')
|
|
749
|
+
);
|
|
750
|
+
|
|
751
|
+
let insertIndex = 0;
|
|
752
|
+
while (insertIndex < body.length && body[insertIndex].type === 'ImportDeclaration')
|
|
753
|
+
insertIndex++;
|
|
754
|
+
|
|
755
|
+
body.splice(insertIndex, 0, importDeclaration);
|
|
756
|
+
}
|
|
757
|
+
|
|
269
758
|
function getFileInfos( filename: string ): TFileInfos {
|
|
270
759
|
|
|
271
760
|
const file: TFileInfos = {
|
|
@@ -282,8 +771,6 @@ function Plugin(babel, { app, side, debug }: TOptions) {
|
|
|
282
771
|
relativeFileName = filename.substring( cli.paths.appRoot.length );
|
|
283
772
|
if (filename.startsWith( cli.paths.coreRoot ))
|
|
284
773
|
relativeFileName = filename.substring( cli.paths.coreRoot.length );
|
|
285
|
-
/*if (filename.startsWith('/node_modules/5htp-core/'))
|
|
286
|
-
relativeFileName = filename.substring( '/node_modules/5htp-core/'.length );*/
|
|
287
774
|
|
|
288
775
|
// The file isn't a route definition
|
|
289
776
|
if (relativeFileName === undefined) {
|
|
@@ -304,7 +791,7 @@ function Plugin(babel, { app, side, debug }: TOptions) {
|
|
|
304
791
|
|
|
305
792
|
function transformDataFetchers(
|
|
306
793
|
path: NodePath<types.CallExpression>,
|
|
307
|
-
routerDefContext:
|
|
794
|
+
routerDefContext: TPluginState,
|
|
308
795
|
routeDef: TRouteDefinition
|
|
309
796
|
) {
|
|
310
797
|
path.traverse({
|
|
@@ -640,4 +1127,4 @@ function Plugin(babel, { app, side, debug }: TOptions) {
|
|
|
640
1127
|
}
|
|
641
1128
|
|
|
642
1129
|
return plugin;
|
|
643
|
-
}
|
|
1130
|
+
}
|
package/compiler/common/index.ts
CHANGED
|
@@ -8,9 +8,6 @@ import dayjs from 'dayjs';
|
|
|
8
8
|
|
|
9
9
|
// Plugins
|
|
10
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
11
|
|
|
15
12
|
// Core
|
|
16
13
|
import cli from '../..';
|
|
@@ -48,6 +45,7 @@ export default function createCommonConfig(
|
|
|
48
45
|
): webpack.Configuration {
|
|
49
46
|
|
|
50
47
|
const dev = mode === 'dev';
|
|
48
|
+
const buildCheck = dev && cli.commandName === 'build';
|
|
51
49
|
const config: webpack.Configuration = {
|
|
52
50
|
|
|
53
51
|
// Project root
|
|
@@ -88,12 +86,6 @@ export default function createCommonConfig(
|
|
|
88
86
|
|
|
89
87
|
}),
|
|
90
88
|
|
|
91
|
-
new PluginIndexage(side === 'client' ? {
|
|
92
|
-
'icones-svg': new IconesSvg(app),
|
|
93
|
-
} : {
|
|
94
|
-
//'injection-dependances': new InjectDeps,
|
|
95
|
-
}),
|
|
96
|
-
|
|
97
89
|
...(side === 'client' && cli.args.analyze ? [
|
|
98
90
|
|
|
99
91
|
new BundleAnalyzerPlugin({
|
|
@@ -136,13 +128,17 @@ export default function createCommonConfig(
|
|
|
136
128
|
// "webpack" The "path" argument must be of type string. Received undefined
|
|
137
129
|
// https://github.com/webpack/webpack/issues/12616
|
|
138
130
|
// Update: Hum it's fixed, just had to update webpack deps
|
|
139
|
-
cache: dev,
|
|
131
|
+
cache: dev && !buildCheck,
|
|
140
132
|
|
|
141
|
-
profile:
|
|
133
|
+
profile: !buildCheck,
|
|
142
134
|
|
|
143
135
|
// Pour bundle-stats
|
|
144
136
|
// https://github.com/relative-ci/bundle-stats/tree/master/packages/cli#webpack-configuration
|
|
145
|
-
stats: {
|
|
137
|
+
stats: buildCheck ? {
|
|
138
|
+
colors: true,
|
|
139
|
+
errorDetails: true,
|
|
140
|
+
timings: true,
|
|
141
|
+
} : {
|
|
146
142
|
cached: dev,
|
|
147
143
|
cachedAssets: dev,
|
|
148
144
|
chunks: dev,
|
|
@@ -160,4 +156,4 @@ export default function createCommonConfig(
|
|
|
160
156
|
|
|
161
157
|
return config;
|
|
162
158
|
|
|
163
|
-
}
|
|
159
|
+
}
|