@kosmojs/dev 0.0.8 → 0.0.10
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 +16 -19
- package/pkg/base-plugin/routes.js +391 -196
- package/pkg/base-plugin/routes.js.map +4 -4
- package/pkg/base-plugin/worker.js +302 -208
- package/pkg/base-plugin/worker.js.map +4 -4
- package/pkg/cli/cli.js +1 -4
- package/pkg/cli/cli.js.map +2 -2
- package/pkg/cli/index.js +1 -6
- package/pkg/cli/index.js.map +2 -2
- package/pkg/cli/templates/@src/api/router.hbs +2 -2
- package/pkg/index.js +294 -201
- package/pkg/index.js.map +4 -4
- package/pkg/src/base-plugin/cache.d.ts +1 -1
- package/pkg/src/base-plugin/routes/nesting.d.ts +5 -0
- package/pkg/src/base-plugin/routes/resolve.d.ts +26 -0
- package/pkg/src/base-plugin/routes.d.ts +6 -12
- package/pkg/stub-generator/index.js +5 -4
- package/pkg/stub-generator/index.js.map +2 -2
- package/pkg/test/@fixtures/app/@src/pages/about/careers/[jobId]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/about/careers/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/about/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/about/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/about/team/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/account/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/account/profile/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/admin/[tenant]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/admin/[tenant]/resources/[[type]]/[...path]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/admin/[tenant]/resources/[[type]]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/admin/[tenant]/resources/[[type]]/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/admin/[tenant]/resources/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/admin/[tenant]/resources/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/admin/[tenant]/settings/general/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/admin/[tenant]/settings/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/admin/[tenant]/settings/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/admin/[tenant]/settings/permissions/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/admin/[tenant]/users/[userId]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/admin/[tenant]/users/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/admin/[tenant]/users/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/admin/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/admin/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/blog/[[category]]/[[tag]]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/blog/[[category]]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/blog/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/blog/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/blog/post/[slug]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/blog/post/[slug]/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/contact/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/contact/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/courses/[courseId]/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/courses/[courseId]/lessons/[[lessonId]]/assignments/[...assignmentPath]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/dashboard/[view]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/dashboard/analytics/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/dashboard/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/dashboard/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/dashboard/settings/billing/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/dashboard/settings/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/dashboard/settings/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/dashboard/settings/notifications/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/dashboard/settings/profile/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/dashboard/settings/security/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/dashboard/settings/security/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/docs/[...path]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/docs/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/docs/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/files/[...filePath]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/files/[...filePath]/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/legal/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/legal/privacy/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/legal/terms/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/news/[category]/articles/[...articlePath]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/news/[category]/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/portal/[clientId]/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/portal/[clientId]/reports/[reportType]/data/[dataView]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/portal/[clientId]/reports/[reportType]/data/[dataView]/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/portal/[clientId]/reports/[reportType]/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/portal/[clientId]/reports/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/portal/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/products/[id]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/products/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/profile/[username]/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/profile/[username]/posts/[postId]/comments/[...thread]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/profile/[username]/posts/[postId]/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/projects/[projectId]/files/[...path]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/projects/[projectId]/files/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/projects/[projectId]/files/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/projects/[projectId]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/projects/[projectId]/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/projects/[projectId]/tasks/[taskId]/comments/[commentId]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/projects/[projectId]/tasks/[taskId]/comments/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/projects/[projectId]/tasks/[taskId]/comments/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/projects/[projectId]/tasks/[taskId]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/projects/[projectId]/tasks/[taskId]/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/projects/[projectId]/tasks/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/projects/[projectId]/tasks/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/projects/[projectId]/team/[userId]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/projects/[projectId]/team/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/projects/[projectId]/team/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/projects/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/projects/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/properties/[[city]]/filters/[...filters]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/properties/filters/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/properties/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/search/[[query]]/[[page]]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/search/[[query]]/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/search/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/[category]/[productId]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/[category]/[productId]/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/cart/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/checkout/confirm/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/checkout/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/checkout/payment/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/checkout/shipping/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/checkout/shipping/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/orders/[orderId]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/orders/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/orders/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/product/[id]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/product/[id]/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/product/[id]/reviews/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/products/[[category]]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/products/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/shop/products/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/signup/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/store/[category]/filters/[...filters]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/store/[category]/sort/[sortBy]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/store/[category]/sort/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/store/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/users/[username]/followers/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/users/[username]/following/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/users/[username]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/users/[username]/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/users/[username]/posts/[postId]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/users/[username]/posts/[postId]/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/users/[username]/posts/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/users/[username]/posts/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/users/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/users/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/workspace/[workspaceId]/analytics/[range]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/workspace/[workspaceId]/analytics/[range]/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/workspace/[workspaceId]/analytics/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/workspace/[workspaceId]/analytics/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/workspace/[workspaceId]/team/[memberId]/permissions/[...permissionPath]/index.d.ts +0 -0
- package/pkg/test/@fixtures/app/@src/pages/workspace/[workspaceId]/team/layout.d.ts +0 -0
- package/pkg/test/@fixtures/app/lib/@src/{api}/articles/[...path]/index.ts/types.d.ts +3 -0
- package/pkg/test/@fixtures/app/lib/@src/{api}/books/[category]/[[author]]/index.ts/types.d.ts +4 -0
- package/pkg/test/@fixtures/app/lib/@src/{api}/books/[category]/index.ts/types.d.ts +3 -0
- package/pkg/test/@fixtures/app/lib/@src/{api}/books/index.ts/types.d.ts +1 -0
- package/pkg/test/@fixtures/app/lib/@src/{api}/files/[[folder]]/[[id]].json/index.ts/types.d.ts +4 -0
- package/pkg/test/@fixtures/app/lib/@src/{api}/files/[[folder]]/index.ts/types.d.ts +3 -0
- package/pkg/test/@fixtures/app/lib/@src/{api}/index/index.ts/types.d.ts +1 -0
- package/pkg/test/@fixtures/app/lib/@src/{api}/pages/[...path].html/index.ts/types.d.ts +3 -0
- package/pkg/test/@fixtures/app/lib/@src/{api}/users/[id].json/index.ts/types.d.ts +3 -0
- package/pkg/test/routes/base.d.ts +4 -0
- package/pkg/test/routes/nesting.test.d.ts +1 -0
|
@@ -7,6 +7,11 @@ import {
|
|
|
7
7
|
} from "@kosmojs/devlib";
|
|
8
8
|
|
|
9
9
|
// src/base-plugin/routes.ts
|
|
10
|
+
import {
|
|
11
|
+
defaults as defaults2
|
|
12
|
+
} from "@kosmojs/devlib";
|
|
13
|
+
|
|
14
|
+
// src/base-plugin/routes/resolve.ts
|
|
10
15
|
import { dirname as dirname2, join, resolve as resolve3 } from "node:path";
|
|
11
16
|
import crc3 from "crc/crc32";
|
|
12
17
|
import picomatch from "picomatch";
|
|
@@ -288,7 +293,7 @@ var cacheFactory = (route, {
|
|
|
288
293
|
const cacheFile = pathResolver({
|
|
289
294
|
appRoot: appRoot2,
|
|
290
295
|
sourceFolder: sourceFolder2
|
|
291
|
-
}).resolve("apiLibDir", route.
|
|
296
|
+
}).resolve("apiLibDir", dirname(route.file), "cache.json");
|
|
292
297
|
const getCache = async (opt) => {
|
|
293
298
|
if (await pathExists(cacheFile)) {
|
|
294
299
|
try {
|
|
@@ -369,22 +374,70 @@ var resolved_types_default = "{{#each resolvedTypes}}\nexport type {{name}} = {{
|
|
|
369
374
|
// src/base-plugin/templates/types.hbs
|
|
370
375
|
var types_default = '{{#each typeDeclarations}}{{text}}\n{{/each}}\n\nexport type {{params.id}} = {\n {{#each paramsSchema}}\n "{{name}}"{{#unless isRequired}}?{{/unless}}:{{#if isRest}} Array<{{/if}}\n {{#if refinement}}{{refinement.text}}{{else}}string{{/if}}\n {{#if isRest}}>{{/if}}\n {{/each}}\n};\n\n{{#each payloadTypes}}\nexport type {{id}} = {{text}};\n{{/each}}\n\n{{#each responseTypes}}\nexport type {{id}} = {{text}};\n{{/each}}\n';
|
|
371
376
|
|
|
372
|
-
// src/base-plugin/routes.ts
|
|
373
|
-
var
|
|
374
|
-
var
|
|
377
|
+
// src/base-plugin/routes/resolve.ts
|
|
378
|
+
var API_INDEX_BASENAME = "index";
|
|
379
|
+
var API_INDEX_PATTERN = `${API_INDEX_BASENAME}.ts`;
|
|
380
|
+
var API_USE_BASENAME = "use";
|
|
381
|
+
var API_USE_PATTERN = `${API_USE_BASENAME}.ts`;
|
|
382
|
+
var PAGE_INDEX_BASENAME = "index";
|
|
383
|
+
var PAGE_INDEX_PATTERN = `${PAGE_INDEX_BASENAME}.{tsx,vue}`;
|
|
384
|
+
var PAGE_LAYOUT_BASENAME = "layout";
|
|
385
|
+
var PAGE_LAYOUT_PATTERN = `${PAGE_LAYOUT_BASENAME}.{tsx,vue}`;
|
|
375
386
|
var ROUTE_FILE_PATTERNS = [
|
|
387
|
+
// match index files in api dir
|
|
376
388
|
`${defaults.apiDir}/**/${API_INDEX_PATTERN}`,
|
|
377
|
-
|
|
389
|
+
// match use files in api dir
|
|
390
|
+
`${defaults.apiDir}/**/${API_USE_PATTERN}`,
|
|
391
|
+
// match index files in pages dir
|
|
392
|
+
`${defaults.pagesDir}/**/${PAGE_INDEX_PATTERN}`,
|
|
393
|
+
// match layout files in pages dir
|
|
394
|
+
`${defaults.pagesDir}/**/${PAGE_LAYOUT_PATTERN}`
|
|
378
395
|
];
|
|
379
|
-
var
|
|
396
|
+
var scanRoutes = async ({
|
|
397
|
+
appRoot: appRoot2,
|
|
398
|
+
sourceFolder: sourceFolder2
|
|
399
|
+
}) => {
|
|
400
|
+
return glob(ROUTE_FILE_PATTERNS, {
|
|
401
|
+
cwd: resolve3(appRoot2, sourceFolder2),
|
|
402
|
+
absolute: true,
|
|
403
|
+
onlyFiles: true,
|
|
404
|
+
followSymbolicLinks: false,
|
|
405
|
+
ignore: [
|
|
406
|
+
// ignore top-level matches, routes resides in folders, even index route
|
|
407
|
+
`${defaults.apiDir}/${API_INDEX_PATTERN}`,
|
|
408
|
+
`${defaults.apiDir}/${API_USE_PATTERN}`,
|
|
409
|
+
`${defaults.pagesDir}/${PAGE_INDEX_PATTERN}`,
|
|
410
|
+
`${defaults.pagesDir}/${PAGE_LAYOUT_PATTERN}`
|
|
411
|
+
]
|
|
412
|
+
});
|
|
413
|
+
};
|
|
414
|
+
var isRouteFile = (file, {
|
|
415
|
+
appRoot: appRoot2,
|
|
416
|
+
sourceFolder: sourceFolder2
|
|
417
|
+
}) => {
|
|
380
418
|
const [_sourceFolder, folder, ...rest] = resolve3(appRoot2, file).replace(`${appRoot2}/`, "").split("/");
|
|
381
419
|
if (!folder || _sourceFolder !== sourceFolder2 || rest.length < 2) {
|
|
382
420
|
return;
|
|
383
421
|
}
|
|
384
422
|
return picomatch.isMatch(join(folder, ...rest), ROUTE_FILE_PATTERNS) ? [folder, rest.join("/")] : void 0;
|
|
385
423
|
};
|
|
386
|
-
var
|
|
387
|
-
|
|
424
|
+
var isApiRoute = (file) => {
|
|
425
|
+
return picomatch.matchBase(file, `**/${API_INDEX_PATTERN}`);
|
|
426
|
+
};
|
|
427
|
+
var isApiUse = (file) => {
|
|
428
|
+
return picomatch.matchBase(file, `**/${API_USE_PATTERN}`);
|
|
429
|
+
};
|
|
430
|
+
var isPageRoute = (file) => {
|
|
431
|
+
return picomatch.matchBase(file, `**/${PAGE_INDEX_PATTERN}`);
|
|
432
|
+
};
|
|
433
|
+
var isPageLayout = (file) => {
|
|
434
|
+
return picomatch.matchBase(file, `**/${PAGE_LAYOUT_PATTERN}`);
|
|
435
|
+
};
|
|
436
|
+
var createRouteEntry = (_file, {
|
|
437
|
+
appRoot: appRoot2,
|
|
438
|
+
sourceFolder: sourceFolder2
|
|
439
|
+
}) => {
|
|
440
|
+
const resolvedPaths = isRouteFile(_file, { appRoot: appRoot2, sourceFolder: sourceFolder2 });
|
|
388
441
|
if (!resolvedPaths) {
|
|
389
442
|
return;
|
|
390
443
|
}
|
|
@@ -392,22 +445,75 @@ var resolveRouteEntry = (_file, { appRoot: appRoot2, sourceFolder: sourceFolder2
|
|
|
392
445
|
const fileFullpath = join(appRoot2, sourceFolder2, folder, file);
|
|
393
446
|
const pathTokens = pathTokensFactory(dirname2(file));
|
|
394
447
|
const name = pathTokens.map((e) => e.orig).join("/");
|
|
395
|
-
const
|
|
396
|
-
const importName =
|
|
397
|
-
importPath.split(/\[/)[0].replace(/^\W+|\W+$/g, "").replace(/\W+/g, "_"),
|
|
398
|
-
crc3(importPath)
|
|
399
|
-
].join("_");
|
|
448
|
+
const importFile = file;
|
|
449
|
+
const importName = `${importFile.replace(/\W+/g, "_")}_${crc3(importFile)}`;
|
|
400
450
|
return {
|
|
401
451
|
name,
|
|
402
452
|
folder,
|
|
403
453
|
file,
|
|
404
454
|
fileFullpath,
|
|
405
455
|
pathTokens,
|
|
406
|
-
|
|
456
|
+
importFile,
|
|
407
457
|
importName
|
|
408
458
|
};
|
|
409
459
|
};
|
|
410
|
-
var
|
|
460
|
+
var pageLayoutResolverFactory = () => {
|
|
461
|
+
return (entry) => {
|
|
462
|
+
const { name } = entry;
|
|
463
|
+
const handler = async () => {
|
|
464
|
+
return {
|
|
465
|
+
kind: "pageLayout",
|
|
466
|
+
entry
|
|
467
|
+
};
|
|
468
|
+
};
|
|
469
|
+
return { name, handler };
|
|
470
|
+
};
|
|
471
|
+
};
|
|
472
|
+
var pageRouteResolverFactory = () => {
|
|
473
|
+
return (entry) => {
|
|
474
|
+
const {
|
|
475
|
+
name,
|
|
476
|
+
folder,
|
|
477
|
+
file,
|
|
478
|
+
fileFullpath,
|
|
479
|
+
pathTokens,
|
|
480
|
+
importFile,
|
|
481
|
+
importName
|
|
482
|
+
} = entry;
|
|
483
|
+
const handler = async () => {
|
|
484
|
+
const entry2 = {
|
|
485
|
+
name,
|
|
486
|
+
pathTokens,
|
|
487
|
+
params: {
|
|
488
|
+
schema: pathTokens.flatMap((e) => e.param ? [e.param] : [])
|
|
489
|
+
},
|
|
490
|
+
folder,
|
|
491
|
+
file,
|
|
492
|
+
fileFullpath,
|
|
493
|
+
importFile,
|
|
494
|
+
importName
|
|
495
|
+
};
|
|
496
|
+
return {
|
|
497
|
+
kind: "pageRoute",
|
|
498
|
+
entry: entry2
|
|
499
|
+
};
|
|
500
|
+
};
|
|
501
|
+
return { name, handler };
|
|
502
|
+
};
|
|
503
|
+
};
|
|
504
|
+
var apiUseResolverFactory = () => {
|
|
505
|
+
return (entry) => {
|
|
506
|
+
const { name } = entry;
|
|
507
|
+
const handler = async () => {
|
|
508
|
+
return {
|
|
509
|
+
kind: "apiUse",
|
|
510
|
+
entry
|
|
511
|
+
};
|
|
512
|
+
};
|
|
513
|
+
return { name, handler };
|
|
514
|
+
};
|
|
515
|
+
};
|
|
516
|
+
var apiRouteResolverFactory = (pluginOptions) => {
|
|
411
517
|
const {
|
|
412
518
|
appRoot: appRoot2,
|
|
413
519
|
sourceFolder: sourceFolder2,
|
|
@@ -427,198 +533,186 @@ var routes_default = async (pluginOptions) => {
|
|
|
427
533
|
getSourceFile,
|
|
428
534
|
refreshSourceFile
|
|
429
535
|
} = typeResolverFactory(pluginOptions);
|
|
430
|
-
|
|
431
|
-
const
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
} =
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
536
|
+
return (entry) => {
|
|
537
|
+
const {
|
|
538
|
+
name,
|
|
539
|
+
file,
|
|
540
|
+
folder,
|
|
541
|
+
fileFullpath,
|
|
542
|
+
pathTokens,
|
|
543
|
+
importFile,
|
|
544
|
+
importName
|
|
545
|
+
} = entry;
|
|
546
|
+
const handler = async (updatedFile) => {
|
|
547
|
+
const paramsSchema = pathTokens.flatMap((e) => {
|
|
548
|
+
return e.param ? [e.param] : [];
|
|
549
|
+
});
|
|
550
|
+
const optionalParams = paramsSchema.length ? !paramsSchema.some((e) => e.isRequired) : true;
|
|
551
|
+
const { getCache, persistCache } = cacheFactory(
|
|
552
|
+
{ file, fileFullpath, importName },
|
|
553
|
+
{
|
|
554
|
+
appRoot: appRoot2,
|
|
555
|
+
sourceFolder: sourceFolder2,
|
|
556
|
+
extraContext: { resolveTypes }
|
|
557
|
+
}
|
|
558
|
+
);
|
|
559
|
+
let cache = await getCache({ validate: true });
|
|
560
|
+
if (!cache) {
|
|
561
|
+
if (updatedFile === fileFullpath) {
|
|
562
|
+
await refreshSourceFile(fileFullpath);
|
|
563
|
+
}
|
|
564
|
+
const {
|
|
565
|
+
typeDeclarations,
|
|
566
|
+
paramsRefinements,
|
|
567
|
+
methods,
|
|
568
|
+
payloadTypes,
|
|
569
|
+
responseTypes,
|
|
570
|
+
referencedFiles = []
|
|
571
|
+
} = await resolveRouteSignature(
|
|
572
|
+
{ importName, fileFullpath, optionalParams },
|
|
453
573
|
{
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
574
|
+
withReferencedFiles: true,
|
|
575
|
+
sourceFile: getSourceFile(fileFullpath),
|
|
576
|
+
relpathResolver(path) {
|
|
577
|
+
return join(sourceFolder2, defaults.apiDir, dirname2(file), path);
|
|
578
|
+
}
|
|
457
579
|
}
|
|
458
580
|
);
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
581
|
+
const numericParams = paramsRefinements ? paramsRefinements.flatMap(({ text, index }) => {
|
|
582
|
+
if (text === "number") {
|
|
583
|
+
const param = paramsSchema.at(index);
|
|
584
|
+
return param ? [param.name] : [];
|
|
463
585
|
}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
sourceFile: getSourceFile(fileFullpath),
|
|
476
|
-
relpathResolver(path) {
|
|
477
|
-
return join(sourceFolder2, defaults.apiDir, dirname2(file), path);
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
);
|
|
481
|
-
const numericParams = paramsRefinements ? paramsRefinements.flatMap(({ text, index }) => {
|
|
482
|
-
if (text === "number") {
|
|
483
|
-
const param = paramsSchema.at(index);
|
|
484
|
-
return param ? [param.name] : [];
|
|
485
|
-
}
|
|
486
|
-
return [];
|
|
487
|
-
}) : [];
|
|
488
|
-
const typesFile = pathResolver2({ appRoot: appRoot2, sourceFolder: sourceFolder2 }).resolve(
|
|
489
|
-
"apiLibDir",
|
|
490
|
-
importPath,
|
|
491
|
-
"types.ts"
|
|
492
|
-
);
|
|
493
|
-
const params = {
|
|
494
|
-
id: ["ParamsT", crc3(name)].join(""),
|
|
495
|
-
schema: paramsSchema,
|
|
496
|
-
resolvedType: void 0
|
|
497
|
-
};
|
|
498
|
-
const typesFileContent = render(types_default, {
|
|
499
|
-
params,
|
|
500
|
-
paramsSchema: paramsSchema.map((param, index) => {
|
|
501
|
-
return {
|
|
502
|
-
...param,
|
|
503
|
-
refinement: paramsRefinements?.at(index)
|
|
504
|
-
};
|
|
505
|
-
}),
|
|
506
|
-
typeDeclarations,
|
|
507
|
-
payloadTypes,
|
|
508
|
-
responseTypes
|
|
509
|
-
});
|
|
510
|
-
const resolvedTypes = resolveTypes ? literalTypesResolver(typesFileContent, {
|
|
511
|
-
overrides: [...payloadTypes, ...responseTypes].reduce(
|
|
512
|
-
(map, { id, skipValidation }) => {
|
|
513
|
-
if (skipValidation) {
|
|
514
|
-
map[id] = "never";
|
|
515
|
-
}
|
|
516
|
-
return map;
|
|
517
|
-
},
|
|
518
|
-
{ [refineTypeName]: refineTypeName }
|
|
519
|
-
),
|
|
520
|
-
withProperties: [params.id, ...payloadTypes.map((e) => e.id)],
|
|
521
|
-
formatters: formatters2
|
|
522
|
-
}) : void 0;
|
|
523
|
-
await renderToFile(
|
|
524
|
-
typesFile,
|
|
525
|
-
resolvedTypes ? resolved_types_default : typesFileContent,
|
|
526
|
-
{ resolvedTypes }
|
|
527
|
-
);
|
|
528
|
-
params.resolvedType = resolvedTypes?.find(
|
|
529
|
-
(e) => e.name === params.id
|
|
530
|
-
);
|
|
531
|
-
cache = await persistCache({
|
|
532
|
-
params,
|
|
533
|
-
methods,
|
|
534
|
-
typeDeclarations,
|
|
535
|
-
numericParams,
|
|
536
|
-
// text was needed at writing types.ts file, dropping from cache
|
|
537
|
-
payloadTypes: payloadTypes.map(({ text, ...rest }) => {
|
|
538
|
-
return {
|
|
539
|
-
...rest,
|
|
540
|
-
resolvedType: resolvedTypes?.find((e) => e.name === rest.id)
|
|
541
|
-
};
|
|
542
|
-
}),
|
|
543
|
-
responseTypes: responseTypes.map(({ text, ...rest }) => {
|
|
544
|
-
return {
|
|
545
|
-
...rest,
|
|
546
|
-
resolvedType: resolvedTypes?.find((e) => e.name === rest.id)
|
|
547
|
-
};
|
|
548
|
-
}),
|
|
549
|
-
referencedFiles
|
|
550
|
-
});
|
|
551
|
-
}
|
|
552
|
-
const route = {
|
|
553
|
-
name,
|
|
554
|
-
pathTokens,
|
|
555
|
-
params: cache.params,
|
|
556
|
-
numericParams: cache.numericParams,
|
|
557
|
-
optionalParams,
|
|
558
|
-
importName,
|
|
559
|
-
importPath,
|
|
560
|
-
folder,
|
|
561
|
-
file,
|
|
562
|
-
fileFullpath,
|
|
563
|
-
methods: cache.methods,
|
|
564
|
-
typeDeclarations: cache.typeDeclarations,
|
|
565
|
-
payloadTypes: cache.payloadTypes,
|
|
566
|
-
responseTypes: cache.responseTypes,
|
|
567
|
-
referencedFiles: Object.keys(cache.referencedFiles).map(
|
|
568
|
-
// expand referenced files path,
|
|
569
|
-
// they are stored as relative in cache
|
|
570
|
-
(e) => resolve3(appRoot2, e)
|
|
571
|
-
)
|
|
572
|
-
};
|
|
573
|
-
return {
|
|
574
|
-
kind: "api",
|
|
575
|
-
route
|
|
586
|
+
return [];
|
|
587
|
+
}) : [];
|
|
588
|
+
const typesFile = pathResolver2({ appRoot: appRoot2, sourceFolder: sourceFolder2 }).resolve(
|
|
589
|
+
"apiLibDir",
|
|
590
|
+
dirname2(file),
|
|
591
|
+
"types.ts"
|
|
592
|
+
);
|
|
593
|
+
const params = {
|
|
594
|
+
id: ["ParamsT", crc3(name)].join(""),
|
|
595
|
+
schema: paramsSchema,
|
|
596
|
+
resolvedType: void 0
|
|
576
597
|
};
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
598
|
+
const typesFileContent = render(types_default, {
|
|
599
|
+
params,
|
|
600
|
+
paramsSchema: paramsSchema.map((param, index) => {
|
|
601
|
+
return {
|
|
602
|
+
...param,
|
|
603
|
+
refinement: paramsRefinements?.at(index)
|
|
604
|
+
};
|
|
605
|
+
}),
|
|
606
|
+
typeDeclarations,
|
|
607
|
+
payloadTypes,
|
|
608
|
+
responseTypes
|
|
609
|
+
});
|
|
610
|
+
const resolvedTypes = resolveTypes ? literalTypesResolver(typesFileContent, {
|
|
611
|
+
overrides: [...payloadTypes, ...responseTypes].reduce(
|
|
612
|
+
(map, { id, skipValidation }) => {
|
|
613
|
+
if (skipValidation) {
|
|
614
|
+
map[id] = "never";
|
|
615
|
+
}
|
|
616
|
+
return map;
|
|
617
|
+
},
|
|
618
|
+
{ [refineTypeName]: refineTypeName }
|
|
619
|
+
),
|
|
620
|
+
withProperties: [params.id, ...payloadTypes.map((e) => e.id)],
|
|
621
|
+
formatters: formatters2
|
|
622
|
+
}) : void 0;
|
|
623
|
+
await renderToFile(
|
|
624
|
+
typesFile,
|
|
625
|
+
resolvedTypes ? resolved_types_default : typesFileContent,
|
|
626
|
+
{ resolvedTypes }
|
|
627
|
+
);
|
|
628
|
+
params.resolvedType = resolvedTypes?.find((e) => e.name === params.id);
|
|
629
|
+
cache = await persistCache({
|
|
630
|
+
params,
|
|
631
|
+
methods,
|
|
632
|
+
typeDeclarations,
|
|
633
|
+
numericParams,
|
|
634
|
+
// text was needed at writing types.ts file, dropping from cache
|
|
635
|
+
payloadTypes: payloadTypes.map(({ text, ...rest }) => {
|
|
636
|
+
return {
|
|
637
|
+
...rest,
|
|
638
|
+
resolvedType: resolvedTypes?.find((e) => e.name === rest.id)
|
|
639
|
+
};
|
|
640
|
+
}),
|
|
641
|
+
responseTypes: responseTypes.map(({ text, ...rest }) => {
|
|
642
|
+
return {
|
|
643
|
+
...rest,
|
|
644
|
+
resolvedType: resolvedTypes?.find((e) => e.name === rest.id)
|
|
645
|
+
};
|
|
646
|
+
}),
|
|
647
|
+
referencedFiles
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
const entry2 = {
|
|
583
651
|
name,
|
|
652
|
+
pathTokens,
|
|
653
|
+
params: cache.params,
|
|
654
|
+
numericParams: cache.numericParams,
|
|
655
|
+
optionalParams,
|
|
656
|
+
importName,
|
|
657
|
+
importFile,
|
|
584
658
|
folder,
|
|
585
659
|
file,
|
|
586
660
|
fileFullpath,
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
fileFullpath,
|
|
601
|
-
importPath,
|
|
602
|
-
importName
|
|
603
|
-
};
|
|
604
|
-
return {
|
|
605
|
-
kind: "page",
|
|
606
|
-
route
|
|
607
|
-
};
|
|
661
|
+
methods: cache.methods,
|
|
662
|
+
typeDeclarations: cache.typeDeclarations,
|
|
663
|
+
payloadTypes: cache.payloadTypes,
|
|
664
|
+
responseTypes: cache.responseTypes,
|
|
665
|
+
referencedFiles: Object.keys(cache.referencedFiles).map(
|
|
666
|
+
// expand referenced files path,
|
|
667
|
+
// they are stored as relative in cache
|
|
668
|
+
(e) => resolve3(appRoot2, e)
|
|
669
|
+
)
|
|
670
|
+
};
|
|
671
|
+
return {
|
|
672
|
+
kind: "apiRoute",
|
|
673
|
+
entry: entry2
|
|
608
674
|
};
|
|
609
|
-
|
|
675
|
+
};
|
|
676
|
+
return { name, handler };
|
|
677
|
+
};
|
|
678
|
+
};
|
|
679
|
+
|
|
680
|
+
// src/base-plugin/routes/nesting.ts
|
|
681
|
+
import {
|
|
682
|
+
sortRoutes
|
|
683
|
+
} from "@kosmojs/devlib";
|
|
684
|
+
|
|
685
|
+
// src/base-plugin/routes.ts
|
|
686
|
+
var routes_default = async (pluginOptions) => {
|
|
687
|
+
const { appRoot: appRoot2, sourceFolder: sourceFolder2 } = pluginOptions;
|
|
688
|
+
const apiRouteResolver = apiRouteResolverFactory(pluginOptions);
|
|
689
|
+
const apiUseResolver = apiUseResolverFactory(pluginOptions);
|
|
690
|
+
const pageRouteResolver = pageRouteResolverFactory(pluginOptions);
|
|
691
|
+
const pageLayoutResolver = pageLayoutResolverFactory(pluginOptions);
|
|
692
|
+
const resolversFactory2 = (routeFiles2) => {
|
|
693
|
+
const resolvers2 = /* @__PURE__ */ new Map();
|
|
694
|
+
const entries = routeFiles2.flatMap((file) => {
|
|
695
|
+
const entry = createRouteEntry(file, pluginOptions);
|
|
696
|
+
return entry ? [entry] : [];
|
|
697
|
+
});
|
|
698
|
+
for (const entry of entries) {
|
|
699
|
+
if (entry.folder === defaults2.apiDir) {
|
|
700
|
+
if (isApiRoute(entry.file)) {
|
|
701
|
+
resolvers2.set(entry.fileFullpath, apiRouteResolver(entry));
|
|
702
|
+
} else if (isApiUse(entry.file)) {
|
|
703
|
+
resolvers2.set(entry.fileFullpath, apiUseResolver(entry));
|
|
704
|
+
}
|
|
705
|
+
} else if (entry.folder === defaults2.pagesDir) {
|
|
706
|
+
if (isPageRoute(entry.file)) {
|
|
707
|
+
resolvers2.set(entry.fileFullpath, pageRouteResolver(entry));
|
|
708
|
+
} else if (isPageLayout(entry.file)) {
|
|
709
|
+
resolvers2.set(entry.fileFullpath, pageLayoutResolver(entry));
|
|
710
|
+
}
|
|
711
|
+
}
|
|
610
712
|
}
|
|
611
713
|
return resolvers2;
|
|
612
714
|
};
|
|
613
|
-
const routeFiles = await
|
|
614
|
-
cwd: resolve3(appRoot2, sourceFolder2),
|
|
615
|
-
absolute: true,
|
|
616
|
-
onlyFiles: true,
|
|
617
|
-
ignore: [
|
|
618
|
-
`${defaults.apiDir}/${API_INDEX_PATTERN}`,
|
|
619
|
-
`${defaults.pagesDir}/${PAGE_INDEX_PATTERN}`
|
|
620
|
-
]
|
|
621
|
-
});
|
|
715
|
+
const routeFiles = await scanRoutes({ appRoot: appRoot2, sourceFolder: sourceFolder2 });
|
|
622
716
|
return {
|
|
623
717
|
resolvers: resolversFactory2(routeFiles),
|
|
624
718
|
resolversFactory: resolversFactory2
|
|
@@ -647,7 +741,7 @@ var resolvedOptions = {
|
|
|
647
741
|
};
|
|
648
742
|
var { appRoot, sourceFolder } = resolvedOptions;
|
|
649
743
|
var watchHandlers = [];
|
|
650
|
-
var
|
|
744
|
+
var resolvedEntries = /* @__PURE__ */ new Map();
|
|
651
745
|
var { resolvers, resolversFactory } = await routes_default(resolvedOptions);
|
|
652
746
|
var { resolve: resolve4 } = pathResolver3({ appRoot, sourceFolder });
|
|
653
747
|
var spinnerFactory = (startText) => {
|
|
@@ -682,9 +776,9 @@ var createEventHandler = async (file) => {
|
|
|
682
776
|
if (resolver) {
|
|
683
777
|
const spinner = spinnerFactory(`Resolving ${resolver.name} Route`);
|
|
684
778
|
try {
|
|
685
|
-
const
|
|
779
|
+
const resolvedEntry = await resolver.handler();
|
|
686
780
|
resolvers.set(file, resolver);
|
|
687
|
-
|
|
781
|
+
resolvedEntries.set(resolvedEntry.entry.fileFullpath, resolvedEntry);
|
|
688
782
|
spinner.succeed();
|
|
689
783
|
} catch (error) {
|
|
690
784
|
spinner.failed(error);
|
|
@@ -693,16 +787,16 @@ var createEventHandler = async (file) => {
|
|
|
693
787
|
};
|
|
694
788
|
var updateEventHandler = async (file) => {
|
|
695
789
|
const relatedResolvers = /* @__PURE__ */ new Map();
|
|
696
|
-
if (
|
|
790
|
+
if (resolvedEntries.has(file)) {
|
|
697
791
|
const resolver = resolvers.get(file);
|
|
698
792
|
if (resolver) {
|
|
699
793
|
relatedResolvers.set(file, resolver);
|
|
700
794
|
}
|
|
701
795
|
} else {
|
|
702
|
-
const referencedRoutes =
|
|
703
|
-
return kind === "
|
|
796
|
+
const referencedRoutes = resolvedEntries.values().flatMap(({ kind, entry }) => {
|
|
797
|
+
return kind === "apiRoute" ? entry.referencedFiles.includes(file) ? [entry] : [] : [];
|
|
704
798
|
});
|
|
705
|
-
for (const
|
|
799
|
+
for (const route of referencedRoutes) {
|
|
706
800
|
const resolver = resolvers.get(route.fileFullpath);
|
|
707
801
|
if (resolver) {
|
|
708
802
|
relatedResolvers.set(route.fileFullpath, resolver);
|
|
@@ -713,8 +807,8 @@ var updateEventHandler = async (file) => {
|
|
|
713
807
|
for (const resolver of relatedResolvers.values()) {
|
|
714
808
|
spinner.append(resolver.name);
|
|
715
809
|
try {
|
|
716
|
-
const
|
|
717
|
-
|
|
810
|
+
const resolvedEntry = await resolver.handler(file);
|
|
811
|
+
resolvedEntries.set(resolvedEntry.entry.fileFullpath, resolvedEntry);
|
|
718
812
|
} catch (error) {
|
|
719
813
|
spinner.failed(error);
|
|
720
814
|
spinner = spinnerFactory(`Updating ${relatedResolvers.size} Routes`);
|
|
@@ -726,11 +820,11 @@ var deleteEventHandler = async () => {
|
|
|
726
820
|
};
|
|
727
821
|
var runWatchHandlers = async (event) => {
|
|
728
822
|
let spinner = spinnerFactory("Running Generators");
|
|
729
|
-
const
|
|
823
|
+
const entries = Array.from(resolvedEntries.values());
|
|
730
824
|
for (const { name, handler } of watchHandlers) {
|
|
731
825
|
spinner.append(name);
|
|
732
826
|
try {
|
|
733
|
-
await handler(structuredClone(
|
|
827
|
+
await handler(structuredClone(entries), event);
|
|
734
828
|
} catch (error) {
|
|
735
829
|
spinner.failed(error);
|
|
736
830
|
spinner = spinnerFactory("Running Generators");
|
|
@@ -760,7 +854,7 @@ watcher.on("all", async (event, file) => {
|
|
|
760
854
|
if (event.endsWith("Dir")) {
|
|
761
855
|
return;
|
|
762
856
|
}
|
|
763
|
-
if (!
|
|
857
|
+
if (!isRouteFile(file, { appRoot, sourceFolder })) {
|
|
764
858
|
return;
|
|
765
859
|
}
|
|
766
860
|
const match = {
|
|
@@ -778,11 +872,11 @@ watcher.on("all", async (event, file) => {
|
|
|
778
872
|
let spinner = spinnerFactory("Resolving Routes");
|
|
779
873
|
for (const { name, handler } of resolvers.values()) {
|
|
780
874
|
spinner.append(
|
|
781
|
-
`[ ${
|
|
875
|
+
`[ ${resolvedEntries.size + 1} of ${resolvers.size} ] ${name}`
|
|
782
876
|
);
|
|
783
877
|
try {
|
|
784
878
|
const resolvedEntry = await handler();
|
|
785
|
-
|
|
879
|
+
resolvedEntries.set(resolvedEntry.entry.fileFullpath, resolvedEntry);
|
|
786
880
|
} catch (error) {
|
|
787
881
|
spinner.failed(error);
|
|
788
882
|
spinner = spinnerFactory("Resolving Routes");
|