@kosmojs/lib 0.0.26 → 0.0.27
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 +10 -7
- package/pkg/ast.d.ts +2 -2
- package/pkg/generators.d.ts +1 -56
- package/pkg/index.d.ts +2 -1
- package/pkg/index.js +345 -209
- package/pkg/index.js.map +4 -4
- package/pkg/paths.d.ts +7 -5
- package/pkg/render.d.ts +6 -11
- package/pkg/routes/base.d.ts +12 -44
- package/pkg/routes/index.d.ts +2 -1
- package/pkg/routes/nesting.d.ts +1 -1
- package/pkg/routes/paths.d.ts +25 -0
- package/pkg/routes/resolve.d.ts +1 -1
- package/pkg/routes/templates.d.ts +2 -0
- package/pkg/tsconfig.d.ts +66 -0
- package/pkg/typebox.d.ts +1 -1
- package/pkg/vite.d.ts +4 -0
- package/pkg/types.d.ts +0 -314
package/pkg/index.js
CHANGED
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
SyntaxKind
|
|
9
9
|
} from "ts-morph";
|
|
10
10
|
import {
|
|
11
|
-
HTTPMethods,
|
|
12
11
|
RequestValidationTargets
|
|
13
|
-
} from "@kosmojs/
|
|
12
|
+
} from "@kosmojs/core";
|
|
13
|
+
import { HTTPMethods } from "@kosmojs/core/api";
|
|
14
14
|
var astFactory = () => {
|
|
15
15
|
const createProject = (opts) => new Project(opts);
|
|
16
16
|
const resolveRouteSignature = async (route, opts) => {
|
|
@@ -400,8 +400,8 @@ var astFactory = () => {
|
|
|
400
400
|
|
|
401
401
|
// src/defaults.ts
|
|
402
402
|
var defaults = {
|
|
403
|
-
appPrefix: "
|
|
404
|
-
srcPrefix: "
|
|
403
|
+
appPrefix: "@",
|
|
404
|
+
srcPrefix: "~",
|
|
405
405
|
libPrefix: "_",
|
|
406
406
|
coreDir: "core",
|
|
407
407
|
srcDir: "src",
|
|
@@ -415,76 +415,37 @@ var defaults = {
|
|
|
415
415
|
};
|
|
416
416
|
|
|
417
417
|
// src/generators.ts
|
|
418
|
-
var
|
|
419
|
-
var defineGenerator = (factory, meta) => {
|
|
420
|
-
const value = meta ? deepFreeze(structuredClone(meta)) : void 0;
|
|
421
|
-
const defineProperty = (fn) => {
|
|
422
|
-
Object.defineProperty(fn, GENERATOR_META, {
|
|
423
|
-
value,
|
|
424
|
-
enumerable: false,
|
|
425
|
-
writable: false,
|
|
426
|
-
configurable: false
|
|
427
|
-
});
|
|
428
|
-
return fn;
|
|
429
|
-
};
|
|
430
|
-
return defineProperty((...args) => {
|
|
431
|
-
return defineProperty(factory(...args));
|
|
432
|
-
});
|
|
433
|
-
};
|
|
434
|
-
var isGenerator = (fn) => {
|
|
435
|
-
return GENERATOR_META in fn;
|
|
436
|
-
};
|
|
437
|
-
var getGeneratorMeta = (fn) => {
|
|
438
|
-
return fn[GENERATOR_META];
|
|
439
|
-
};
|
|
418
|
+
var defineGenerator = (f) => f;
|
|
440
419
|
var defineGeneratorFactory = (f) => f;
|
|
441
|
-
var deepFreeze = (obj) => {
|
|
442
|
-
if (obj && typeof obj === "object" && !Object.isFrozen(obj)) {
|
|
443
|
-
Object.freeze(obj);
|
|
444
|
-
for (const prop of Object.getOwnPropertyNames(obj)) {
|
|
445
|
-
deepFreeze(obj[prop]);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
return obj;
|
|
449
|
-
};
|
|
450
420
|
|
|
451
421
|
// src/paths.ts
|
|
452
422
|
import { access, constants } from "node:fs/promises";
|
|
453
423
|
import { join, resolve as resolve2 } from "node:path";
|
|
454
|
-
var createTsconfigPaths = (prefix) => {
|
|
455
|
-
return {
|
|
456
|
-
[`${defaults.appPrefix}/*`]: [`${prefix}/*`],
|
|
457
|
-
[`${defaults.srcPrefix}/*`]: [`${prefix}/${defaults.srcDir}/*`],
|
|
458
|
-
[`${defaults.libPrefix}/*`]: [
|
|
459
|
-
`${prefix}/${defaults.libDir}/${defaults.srcDir}/*`
|
|
460
|
-
]
|
|
461
|
-
};
|
|
462
|
-
};
|
|
463
424
|
var pathResolver = (sourceFolder) => {
|
|
464
425
|
const createPath = (...a) => {
|
|
465
426
|
return sourceFolder.root ? resolve2(sourceFolder.root, join(...a)) : join(...a);
|
|
466
427
|
};
|
|
467
428
|
const createImport = {
|
|
468
|
-
src(
|
|
469
|
-
return join(defaults.srcPrefix, sourceFolder.name, ...a);
|
|
429
|
+
src(a, { origin }) {
|
|
430
|
+
return origin === "src" ? join(defaults.srcPrefix, ...a) : join(defaults.appPrefix, defaults.srcDir, sourceFolder.name, ...a);
|
|
470
431
|
},
|
|
471
|
-
config(
|
|
472
|
-
return this.src(defaults.configDir, ...a);
|
|
432
|
+
config(a, o) {
|
|
433
|
+
return this.src([defaults.configDir, ...a], o);
|
|
473
434
|
},
|
|
474
|
-
api(
|
|
475
|
-
return this.src(defaults.apiDir, ...a);
|
|
435
|
+
api(a, o) {
|
|
436
|
+
return this.src([defaults.apiDir, ...a], o);
|
|
476
437
|
},
|
|
477
|
-
pages(
|
|
478
|
-
return this.src(defaults.pagesDir, ...a);
|
|
438
|
+
pages(a, o) {
|
|
439
|
+
return this.src([defaults.pagesDir, ...a], o);
|
|
479
440
|
},
|
|
480
|
-
lib(
|
|
481
|
-
return join(defaults.libPrefix, sourceFolder.name, ...a);
|
|
441
|
+
lib(a, { origin }) {
|
|
442
|
+
return origin === "src" ? join(defaults.libPrefix, ...a) : join(defaults.appPrefix, defaults.libDir, sourceFolder.name, ...a);
|
|
482
443
|
},
|
|
483
|
-
libApi(
|
|
484
|
-
return this.lib(defaults.apiDir, ...a);
|
|
444
|
+
libApi(a, o) {
|
|
445
|
+
return this.lib([defaults.apiDir, ...a], o);
|
|
485
446
|
},
|
|
486
|
-
libEntry(
|
|
487
|
-
return this.lib(defaults.entryDir, ...a);
|
|
447
|
+
libEntry(a, o) {
|
|
448
|
+
return this.lib([defaults.entryDir, ...a], o);
|
|
488
449
|
}
|
|
489
450
|
};
|
|
490
451
|
return {
|
|
@@ -505,12 +466,7 @@ var pathResolver = (sourceFolder) => {
|
|
|
505
466
|
return this.src(defaults.entryDir, ...a);
|
|
506
467
|
},
|
|
507
468
|
lib(...a) {
|
|
508
|
-
return createPath(
|
|
509
|
-
defaults.libDir,
|
|
510
|
-
defaults.srcDir,
|
|
511
|
-
sourceFolder.name,
|
|
512
|
-
...a
|
|
513
|
-
);
|
|
469
|
+
return createPath(defaults.libDir, sourceFolder.name, ...a);
|
|
514
470
|
},
|
|
515
471
|
libApi(...a) {
|
|
516
472
|
return this.lib(defaults.apiDir, ...a);
|
|
@@ -526,8 +482,17 @@ var pathResolver = (sourceFolder) => {
|
|
|
526
482
|
}
|
|
527
483
|
},
|
|
528
484
|
createImport,
|
|
529
|
-
|
|
530
|
-
|
|
485
|
+
createImportHelpers(o) {
|
|
486
|
+
if (!["src", "lib"].includes(o?.origin)) {
|
|
487
|
+
throw new Error(
|
|
488
|
+
`createImportHelpers: required exactly one argument of shape { origin: "src|lib" }`
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
return {
|
|
492
|
+
createImport(key, ...a) {
|
|
493
|
+
return createImport[key](a.slice(0, -1), o);
|
|
494
|
+
}
|
|
495
|
+
};
|
|
531
496
|
}
|
|
532
497
|
};
|
|
533
498
|
};
|
|
@@ -568,15 +533,24 @@ var renderToFile = async (file, template, context, options) => {
|
|
|
568
533
|
await writeFile(file, content, "utf8");
|
|
569
534
|
};
|
|
570
535
|
var renderFactory = (options) => {
|
|
571
|
-
const
|
|
572
|
-
|
|
573
|
-
|
|
536
|
+
const createRenderer = (selfOoptions) => {
|
|
537
|
+
const renderer = handlebars.create();
|
|
538
|
+
renderer.registerPartial({
|
|
539
|
+
...options?.partials,
|
|
540
|
+
...selfOoptions?.partials
|
|
541
|
+
});
|
|
542
|
+
renderer.registerHelper({
|
|
543
|
+
...options?.helpers,
|
|
544
|
+
...selfOoptions?.helpers
|
|
545
|
+
});
|
|
546
|
+
return renderer;
|
|
547
|
+
};
|
|
574
548
|
return {
|
|
575
549
|
render(template, context, selfOoptions) {
|
|
576
550
|
return render(template, context, {
|
|
577
|
-
renderer,
|
|
578
551
|
...options,
|
|
579
|
-
...selfOoptions
|
|
552
|
+
...selfOoptions,
|
|
553
|
+
renderer: createRenderer(selfOoptions)
|
|
580
554
|
});
|
|
581
555
|
},
|
|
582
556
|
async renderToFile(file, template, context, selfOoptions) {
|
|
@@ -584,98 +558,26 @@ var renderFactory = (options) => {
|
|
|
584
558
|
options?.outdir ? join2(options.outdir, file) : file,
|
|
585
559
|
template,
|
|
586
560
|
context,
|
|
587
|
-
{
|
|
561
|
+
{
|
|
562
|
+
...options,
|
|
563
|
+
...selfOoptions,
|
|
564
|
+
renderer: createRenderer(selfOoptions)
|
|
565
|
+
}
|
|
588
566
|
);
|
|
589
567
|
}
|
|
590
568
|
};
|
|
591
569
|
};
|
|
592
|
-
var renderHelpers = {
|
|
593
|
-
createParamsLiteral: (params) => {
|
|
594
|
-
return params.schema.map((p) => {
|
|
595
|
-
return p.kind === "splat" ? `${p.const}?: Array<string | number>` : p.kind === "optional" ? `${p.const}?: string | number` : `${p.const}: string | number`;
|
|
596
|
-
}).join(", ");
|
|
597
|
-
}
|
|
598
|
-
};
|
|
599
570
|
|
|
600
571
|
// src/routes/base.ts
|
|
601
572
|
import { dirname as dirname2, join as join3, resolve as resolve3 } from "node:path";
|
|
602
573
|
import { styleText as styleText2 } from "node:util";
|
|
603
|
-
import
|
|
604
|
-
import { parse } from "path-to-regexp";
|
|
574
|
+
import crc4 from "crc/crc32";
|
|
605
575
|
import picomatch from "picomatch";
|
|
606
576
|
import { glob } from "tinyglobby";
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
var PAGE_INDEX_BASENAME = "index";
|
|
612
|
-
var PAGE_INDEX_PATTERN = `${PAGE_INDEX_BASENAME}.{tsx,vue}`;
|
|
613
|
-
var PAGE_LAYOUT_BASENAME = "layout";
|
|
614
|
-
var PAGE_LAYOUT_PATTERN = `${PAGE_LAYOUT_BASENAME}.{tsx,vue}`;
|
|
615
|
-
var ROUTE_FILE_PATTERNS = [
|
|
616
|
-
// match index files in api dir
|
|
617
|
-
`${defaults.apiDir}/**/${API_INDEX_PATTERN}`,
|
|
618
|
-
// match use files in api dir
|
|
619
|
-
`${defaults.apiDir}/**/${API_USE_PATTERN}`,
|
|
620
|
-
// match index files in pages dir
|
|
621
|
-
`${defaults.pagesDir}/**/${PAGE_INDEX_PATTERN}`,
|
|
622
|
-
// match layout files in pages dir
|
|
623
|
-
`${defaults.pagesDir}/**/${PAGE_LAYOUT_PATTERN}`
|
|
624
|
-
];
|
|
625
|
-
var scanRoutes = async (sourceFolder) => {
|
|
626
|
-
const { createPath } = pathResolver(sourceFolder);
|
|
627
|
-
return glob(ROUTE_FILE_PATTERNS, {
|
|
628
|
-
cwd: createPath.src(),
|
|
629
|
-
absolute: true,
|
|
630
|
-
onlyFiles: true,
|
|
631
|
-
followSymbolicLinks: false,
|
|
632
|
-
ignore: [
|
|
633
|
-
// ignore top-level matches, routes resides in folders, even index route
|
|
634
|
-
`${defaults.apiDir}/${API_INDEX_PATTERN}`,
|
|
635
|
-
`${defaults.apiDir}/${API_USE_PATTERN}`,
|
|
636
|
-
`${defaults.pagesDir}/${PAGE_INDEX_PATTERN}`,
|
|
637
|
-
`${defaults.pagesDir}/${PAGE_LAYOUT_PATTERN}`
|
|
638
|
-
]
|
|
639
|
-
});
|
|
640
|
-
};
|
|
641
|
-
var isRouteFile = (file, sourceFolder) => {
|
|
642
|
-
const [_sourceFolder, _folder, ...rest] = resolve3(sourceFolder.root, file).replace(`${sourceFolder.root}/${defaults.srcDir}/`, "").split("/");
|
|
643
|
-
if (!_folder || _sourceFolder !== sourceFolder.name || rest.length < 2) {
|
|
644
|
-
return false;
|
|
645
|
-
}
|
|
646
|
-
return picomatch.isMatch(join3(_folder, ...rest), ROUTE_FILE_PATTERNS) ? [_folder, rest.join("/")] : false;
|
|
647
|
-
};
|
|
648
|
-
var isApiRoute = (file) => {
|
|
649
|
-
return picomatch.matchBase(file, `**/${API_INDEX_PATTERN}`);
|
|
650
|
-
};
|
|
651
|
-
var isApiUse = (file) => {
|
|
652
|
-
return picomatch.matchBase(file, `**/${API_USE_PATTERN}`);
|
|
653
|
-
};
|
|
654
|
-
var isPageRoute = (file) => {
|
|
655
|
-
return picomatch.matchBase(file, `**/${PAGE_INDEX_PATTERN}`);
|
|
656
|
-
};
|
|
657
|
-
var isPageLayout = (file) => {
|
|
658
|
-
return picomatch.matchBase(file, `**/${PAGE_LAYOUT_PATTERN}`);
|
|
659
|
-
};
|
|
660
|
-
var createRouteEntry = (fileFullpath, sourceFolder) => {
|
|
661
|
-
const resolvedPaths = isRouteFile(fileFullpath, sourceFolder);
|
|
662
|
-
if (!resolvedPaths) {
|
|
663
|
-
return;
|
|
664
|
-
}
|
|
665
|
-
const [folder, file] = resolvedPaths;
|
|
666
|
-
const id = `${file.replace(/\W+/g, "_")}_${crc3(file)}`;
|
|
667
|
-
const name = dirname2(file);
|
|
668
|
-
try {
|
|
669
|
-
const [pathTokens, pathPattern] = pathTokensFactory(dirname2(file));
|
|
670
|
-
return { id, name, folder, file, fileFullpath, pathTokens, pathPattern };
|
|
671
|
-
} catch (error) {
|
|
672
|
-
console.error(
|
|
673
|
-
`\u2757${styleText2("red", "ERROR")}: Failed parsing path for "${styleText2("cyan", file)}"`
|
|
674
|
-
);
|
|
675
|
-
console.error(error);
|
|
676
|
-
return;
|
|
677
|
-
}
|
|
678
|
-
};
|
|
577
|
+
|
|
578
|
+
// src/routes/paths.ts
|
|
579
|
+
import crc3 from "crc/crc32";
|
|
580
|
+
import { parse } from "path-to-regexp";
|
|
679
581
|
var pathTokensFactory = (path, {
|
|
680
582
|
transformStaticValue = normalizeStaticValue
|
|
681
583
|
} = {}) => {
|
|
@@ -781,70 +683,216 @@ var pathTokensFactory = (path, {
|
|
|
781
683
|
}
|
|
782
684
|
];
|
|
783
685
|
});
|
|
784
|
-
return
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
686
|
+
return tokens;
|
|
687
|
+
};
|
|
688
|
+
var createPathPattern = (tokens) => {
|
|
689
|
+
return tokens.map(({ pattern }, i) => {
|
|
690
|
+
const next = tokens[i + 1];
|
|
691
|
+
if (!next || next.pattern.includes("/")) {
|
|
692
|
+
return pattern;
|
|
693
|
+
}
|
|
694
|
+
const slashRequired = tokens.slice(i + 1).some((e) => {
|
|
695
|
+
return e.parts.some((e2) => {
|
|
696
|
+
return e2.type === "static" || e2.kind === "required";
|
|
795
697
|
});
|
|
796
|
-
|
|
797
|
-
}
|
|
798
|
-
|
|
698
|
+
});
|
|
699
|
+
return slashRequired ? `${pattern}/` : pattern;
|
|
700
|
+
}).join("");
|
|
701
|
+
};
|
|
702
|
+
var createHonoPattern = (tokens) => {
|
|
703
|
+
const staticValue = ({ value }) => {
|
|
704
|
+
return normalizeStaticValue(value);
|
|
705
|
+
};
|
|
706
|
+
const paramValue = (p) => {
|
|
707
|
+
if (p.kind === "splat") {
|
|
708
|
+
return `*`;
|
|
709
|
+
}
|
|
710
|
+
if (p.kind === "optional") {
|
|
711
|
+
return `:${p.name}?`;
|
|
712
|
+
}
|
|
713
|
+
return `:${p.name}`;
|
|
714
|
+
};
|
|
715
|
+
const escapeRegex = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
716
|
+
const tokensToRegex = (tokens2) => {
|
|
717
|
+
return tokens2.flatMap((t) => {
|
|
718
|
+
if (t.type === "text") {
|
|
719
|
+
return t.value === "/" ? [] : [escapeRegex(t.value)];
|
|
720
|
+
}
|
|
721
|
+
if (t.type === "wildcard") {
|
|
722
|
+
return [".+"];
|
|
723
|
+
}
|
|
724
|
+
if (t.type === "param") {
|
|
725
|
+
return ["[^/]+"];
|
|
726
|
+
}
|
|
727
|
+
if (t.type === "group") {
|
|
728
|
+
return [`(?:${tokensToRegex(t.tokens)})?`];
|
|
729
|
+
}
|
|
730
|
+
return [];
|
|
731
|
+
}).join("");
|
|
732
|
+
};
|
|
733
|
+
return tokens.flatMap((token, i) => {
|
|
734
|
+
if (token.kind === "static") {
|
|
735
|
+
return [staticValue(token.parts[0])];
|
|
736
|
+
}
|
|
737
|
+
if (token.kind === "param") {
|
|
738
|
+
return [paramValue(token.parts[0])];
|
|
739
|
+
}
|
|
740
|
+
const { tokens: tokens2 } = parse(token.pattern.replace(/\//g, ""));
|
|
741
|
+
const regex = tokensToRegex(tokens2);
|
|
742
|
+
return [`:_${i}{${regex}}`];
|
|
743
|
+
}).join("/");
|
|
799
744
|
};
|
|
800
745
|
var normalizeStaticValue = (value) => {
|
|
801
746
|
return value.replace(/\+/g, "\\\\+");
|
|
802
747
|
};
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
748
|
+
|
|
749
|
+
// src/routes/base.ts
|
|
750
|
+
var API_INDEX_BASENAME = "index";
|
|
751
|
+
var API_INDEX_PATTERN = `${API_INDEX_BASENAME}.ts`;
|
|
752
|
+
var API_USE_BASENAME = "use";
|
|
753
|
+
var API_USE_PATTERN = `${API_USE_BASENAME}.ts`;
|
|
754
|
+
var PAGE_INDEX_BASENAME = "index";
|
|
755
|
+
var PAGE_INDEX_PATTERN = `${PAGE_INDEX_BASENAME}.{tsx,vue,mdx,md}`;
|
|
756
|
+
var PAGE_LAYOUT_BASENAME = "layout";
|
|
757
|
+
var PAGE_LAYOUT_PATTERN = `${PAGE_LAYOUT_BASENAME}.{tsx,vue,mdx}`;
|
|
758
|
+
var ROUTE_FILE_PATTERNS = [
|
|
759
|
+
// match index files in api dir
|
|
760
|
+
`${defaults.apiDir}/**/${API_INDEX_PATTERN}`,
|
|
761
|
+
// match use files in api dir
|
|
762
|
+
`${defaults.apiDir}/**/${API_USE_PATTERN}`,
|
|
763
|
+
// match index files in pages dir
|
|
764
|
+
`${defaults.pagesDir}/**/${PAGE_INDEX_PATTERN}`,
|
|
765
|
+
// match layout files in pages dir
|
|
766
|
+
`${defaults.pagesDir}/**/${PAGE_LAYOUT_PATTERN}`
|
|
767
|
+
];
|
|
768
|
+
var scanRoutes = async (sourceFolder) => {
|
|
769
|
+
const { createPath } = pathResolver(sourceFolder);
|
|
770
|
+
return glob(ROUTE_FILE_PATTERNS, {
|
|
771
|
+
cwd: createPath.src(),
|
|
772
|
+
absolute: true,
|
|
773
|
+
onlyFiles: true,
|
|
774
|
+
followSymbolicLinks: false,
|
|
775
|
+
ignore: [
|
|
776
|
+
// ignore top-level matches, routes resides in folders, even index route
|
|
777
|
+
`${defaults.apiDir}/${API_INDEX_PATTERN}`,
|
|
778
|
+
`${defaults.apiDir}/${API_USE_PATTERN}`,
|
|
779
|
+
`${defaults.pagesDir}/${PAGE_INDEX_PATTERN}`,
|
|
780
|
+
`${defaults.pagesDir}/${PAGE_LAYOUT_PATTERN}`
|
|
781
|
+
]
|
|
782
|
+
});
|
|
783
|
+
};
|
|
784
|
+
var isRouteFile = (file, sourceFolder) => {
|
|
785
|
+
const [
|
|
786
|
+
// source folder name
|
|
787
|
+
_sourceFolder,
|
|
788
|
+
// route folder, api or pages
|
|
789
|
+
_folder,
|
|
790
|
+
...rest
|
|
791
|
+
] = resolve3(sourceFolder.root, file).replace(`${sourceFolder.root}/${defaults.srcDir}/`, "").split("/");
|
|
792
|
+
if (!_folder || _sourceFolder !== sourceFolder.name || rest.length < 2) {
|
|
793
|
+
return false;
|
|
811
794
|
}
|
|
812
|
-
return
|
|
795
|
+
return picomatch.isMatch(join3(_folder, ...rest), ROUTE_FILE_PATTERNS) ? [_folder, rest.join("/")] : false;
|
|
813
796
|
};
|
|
814
|
-
var
|
|
815
|
-
return {
|
|
816
|
-
required: 2,
|
|
817
|
-
optional: 1,
|
|
818
|
-
splat: 0
|
|
819
|
-
}[part.kind];
|
|
797
|
+
var isApiRoute = (file) => {
|
|
798
|
+
return picomatch.matchBase(file, `**/${API_INDEX_PATTERN}`);
|
|
820
799
|
};
|
|
821
|
-
var
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
return
|
|
800
|
+
var isApiUse = (file) => {
|
|
801
|
+
return picomatch.matchBase(file, `**/${API_USE_PATTERN}`);
|
|
802
|
+
};
|
|
803
|
+
var isPageRoute = (file) => {
|
|
804
|
+
return picomatch.matchBase(file, `**/${PAGE_INDEX_PATTERN}`);
|
|
805
|
+
};
|
|
806
|
+
var isPageLayout = (file) => {
|
|
807
|
+
return picomatch.matchBase(file, `**/${PAGE_LAYOUT_PATTERN}`);
|
|
808
|
+
};
|
|
809
|
+
var createRouteEntry = (fileFullpath, sourceFolder) => {
|
|
810
|
+
const resolvedPaths = isRouteFile(fileFullpath, sourceFolder);
|
|
811
|
+
if (!resolvedPaths) {
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
const [folder, file] = resolvedPaths;
|
|
815
|
+
const id = `${file.replace(/\W+/g, "_")}_${crc4(file)}`;
|
|
816
|
+
const name = dirname2(file);
|
|
817
|
+
try {
|
|
818
|
+
const pathTokens = pathTokensFactory(dirname2(file));
|
|
819
|
+
return {
|
|
820
|
+
id,
|
|
821
|
+
name,
|
|
822
|
+
folder,
|
|
823
|
+
file,
|
|
824
|
+
fileFullpath,
|
|
825
|
+
pathTokens,
|
|
826
|
+
pathPattern: createPathPattern(pathTokens),
|
|
827
|
+
honoPattern: createHonoPattern(pathTokens)
|
|
828
|
+
};
|
|
829
|
+
} catch (error) {
|
|
830
|
+
console.error(
|
|
831
|
+
`\u2757${styleText2("red", "ERROR")}: Failed parsing path for "${styleText2("cyan", file)}"`
|
|
832
|
+
);
|
|
833
|
+
console.error(error);
|
|
834
|
+
return;
|
|
835
|
+
}
|
|
826
836
|
};
|
|
827
837
|
var segmentWeight = (token) => {
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
838
|
+
if (token.kind === "static") {
|
|
839
|
+
return 4;
|
|
840
|
+
}
|
|
841
|
+
if (token.kind === "mixed") {
|
|
842
|
+
let statics = 0;
|
|
843
|
+
let optionals = 0;
|
|
844
|
+
for (const part2 of token.parts) {
|
|
845
|
+
if (part2.type === "static") {
|
|
846
|
+
statics += 1;
|
|
847
|
+
} else if (part2.kind === "optional" || part2.kind === "splat") {
|
|
848
|
+
optionals += 1;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
return 3 + statics * 0.01 - optionals * 5e-3;
|
|
852
|
+
}
|
|
853
|
+
const part = token.parts[0];
|
|
854
|
+
switch (part.kind) {
|
|
855
|
+
case "required":
|
|
856
|
+
return 2;
|
|
857
|
+
case "optional":
|
|
858
|
+
return 1;
|
|
859
|
+
case "splat":
|
|
860
|
+
return 0;
|
|
861
|
+
}
|
|
833
862
|
};
|
|
834
|
-
var
|
|
835
|
-
|
|
863
|
+
var sortRoutes = (a, b) => {
|
|
864
|
+
const pairs = Array.from(
|
|
865
|
+
{ length: Math.max(a.pathTokens.length, b.pathTokens.length) },
|
|
866
|
+
(_, i) => [a.pathTokens[i], b.pathTokens[i]]
|
|
867
|
+
);
|
|
868
|
+
for (const [at, bt] of pairs) {
|
|
869
|
+
if (!at || !bt) {
|
|
870
|
+
const extra = at ?? bt;
|
|
871
|
+
const isSplat = extra?.kind === "param" ? extra.parts[0].kind === "splat" : false;
|
|
872
|
+
if (isSplat) {
|
|
873
|
+
return at ? 1 : -1;
|
|
874
|
+
}
|
|
875
|
+
return at ? -1 : 1;
|
|
876
|
+
}
|
|
877
|
+
const aw = segmentWeight(at);
|
|
878
|
+
const bw = segmentWeight(bt);
|
|
879
|
+
if (aw !== bw) {
|
|
880
|
+
return bw - aw;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
return a.pathPattern.localeCompare(b.pathPattern);
|
|
836
884
|
};
|
|
837
885
|
|
|
838
886
|
// src/routes/resolve.ts
|
|
839
887
|
import { dirname as dirname3, join as join4, resolve as resolve4 } from "node:path";
|
|
840
888
|
import { styleText as styleText3 } from "node:util";
|
|
841
|
-
import
|
|
889
|
+
import crc5 from "crc/crc32";
|
|
842
890
|
import mimeTypes from "mime-types";
|
|
843
891
|
|
|
844
|
-
// src/
|
|
892
|
+
// src/templates/resolved-types.hbs
|
|
845
893
|
var resolved_types_default = "{{#each resolvedTypes}}\nexport type {{name}} = {{text}};\n{{/each}}\n";
|
|
846
894
|
|
|
847
|
-
// src/
|
|
895
|
+
// src/templates/types.hbs
|
|
848
896
|
var types_default = '{{#each typeDeclarations}}{{text}}\n{{/each}}\n\nexport type {{params.id}} = {\n {{#each paramsSchema}}\n "{{name}}"{{#unless isRequired}}?{{/unless}}: {{#if refinement}}\n {{refinement.text}},\n {{else}}\n {{#if isSplat}}Array<string>{{else}}string{{/if}},\n {{/if}}\n {{/each}}\n};\n\n{{#each validationTypes}}export type {{id}} = {{text}};\n{{/each}}\n';
|
|
849
897
|
|
|
850
898
|
// src/routes/resolve.ts
|
|
@@ -855,9 +903,7 @@ var resolverFactory = (sourceFolder, cacheFactory) => {
|
|
|
855
903
|
refineTypeName = defaults.refineTypeName
|
|
856
904
|
} = sourceFolder.config;
|
|
857
905
|
const { typeResolverFactory, resolveRouteSignature } = astFactory();
|
|
858
|
-
const resolveTypes = generators.some(
|
|
859
|
-
(e) => getGeneratorMeta(e)?.resolveTypes
|
|
860
|
-
);
|
|
906
|
+
const resolveTypes = generators.some(({ meta }) => meta.resolveTypes);
|
|
861
907
|
const {
|
|
862
908
|
//
|
|
863
909
|
literalTypesResolver,
|
|
@@ -876,13 +922,23 @@ var resolverFactory = (sourceFolder, cacheFactory) => {
|
|
|
876
922
|
return { name, handler };
|
|
877
923
|
},
|
|
878
924
|
pageRouteResolver(entry) {
|
|
879
|
-
const {
|
|
925
|
+
const {
|
|
926
|
+
id,
|
|
927
|
+
name,
|
|
928
|
+
folder,
|
|
929
|
+
file,
|
|
930
|
+
fileFullpath,
|
|
931
|
+
pathTokens,
|
|
932
|
+
pathPattern,
|
|
933
|
+
honoPattern
|
|
934
|
+
} = entry;
|
|
880
935
|
const handler = async () => {
|
|
881
936
|
const entry2 = {
|
|
882
937
|
id,
|
|
883
938
|
name,
|
|
884
939
|
pathTokens,
|
|
885
940
|
pathPattern,
|
|
941
|
+
honoPattern,
|
|
886
942
|
params: {
|
|
887
943
|
schema: pathTokens.flatMap((e) => {
|
|
888
944
|
return e.parts.filter((p) => p.type === "param");
|
|
@@ -911,14 +967,14 @@ var resolverFactory = (sourceFolder, cacheFactory) => {
|
|
|
911
967
|
},
|
|
912
968
|
apiRouteResolver(entry) {
|
|
913
969
|
const {
|
|
914
|
-
//
|
|
915
970
|
id,
|
|
916
971
|
name,
|
|
917
972
|
file,
|
|
918
973
|
folder,
|
|
919
974
|
fileFullpath,
|
|
920
975
|
pathTokens,
|
|
921
|
-
pathPattern
|
|
976
|
+
pathPattern,
|
|
977
|
+
honoPattern
|
|
922
978
|
} = entry;
|
|
923
979
|
const handler = async (updatedFile) => {
|
|
924
980
|
const paramsSchema = pathTokens.flatMap(
|
|
@@ -975,7 +1031,7 @@ var resolverFactory = (sourceFolder, cacheFactory) => {
|
|
|
975
1031
|
"types.ts"
|
|
976
1032
|
);
|
|
977
1033
|
const params = {
|
|
978
|
-
id: ["ParamsT",
|
|
1034
|
+
id: ["ParamsT", crc5(name)].join(""),
|
|
979
1035
|
schema: paramsSchema,
|
|
980
1036
|
resolvedType: void 0
|
|
981
1037
|
};
|
|
@@ -1109,6 +1165,7 @@ var resolverFactory = (sourceFolder, cacheFactory) => {
|
|
|
1109
1165
|
name,
|
|
1110
1166
|
pathTokens,
|
|
1111
1167
|
pathPattern,
|
|
1168
|
+
honoPattern,
|
|
1112
1169
|
params: cache.params,
|
|
1113
1170
|
numericParams: cache.numericParams,
|
|
1114
1171
|
optionalParams,
|
|
@@ -1288,6 +1345,71 @@ var spinnerFactory = (startText) => {
|
|
|
1288
1345
|
};
|
|
1289
1346
|
var withSpinner = (text, pipe, spinner) => pipe(spinner || spinnerFactory(text));
|
|
1290
1347
|
|
|
1348
|
+
// src/tsconfig.ts
|
|
1349
|
+
var generateTsconfig = (sourceFolder) => {
|
|
1350
|
+
const rootDir = "${configDir}";
|
|
1351
|
+
const compilerOptions = {
|
|
1352
|
+
types: ["@types/node", "@types/deno", "@types/bun"],
|
|
1353
|
+
moduleResolution: "bundler",
|
|
1354
|
+
module: "ESNext",
|
|
1355
|
+
target: "ESNext",
|
|
1356
|
+
strict: true,
|
|
1357
|
+
exactOptionalPropertyTypes: true,
|
|
1358
|
+
noImplicitAny: true,
|
|
1359
|
+
noImplicitThis: true,
|
|
1360
|
+
noImplicitOverride: true,
|
|
1361
|
+
noImplicitReturns: true,
|
|
1362
|
+
noUnusedLocals: false,
|
|
1363
|
+
noUnusedParameters: false,
|
|
1364
|
+
allowArbitraryExtensions: true,
|
|
1365
|
+
allowImportingTsExtensions: true,
|
|
1366
|
+
allowUnreachableCode: false,
|
|
1367
|
+
allowUnusedLabels: false,
|
|
1368
|
+
useUnknownInCatchVariables: true,
|
|
1369
|
+
noFallthroughCasesInSwitch: true,
|
|
1370
|
+
noUncheckedSideEffectImports: true,
|
|
1371
|
+
resolveJsonModule: true,
|
|
1372
|
+
esModuleInterop: true,
|
|
1373
|
+
verbatimModuleSyntax: true,
|
|
1374
|
+
skipLibCheck: true,
|
|
1375
|
+
noEmit: true
|
|
1376
|
+
};
|
|
1377
|
+
if (sourceFolder) {
|
|
1378
|
+
return {
|
|
1379
|
+
include: [
|
|
1380
|
+
`${rootDir}/`,
|
|
1381
|
+
`${rootDir}/../../${defaults.libDir}/${sourceFolder}/`,
|
|
1382
|
+
`${rootDir}/../../${defaults.libDir}/env.d.ts`
|
|
1383
|
+
],
|
|
1384
|
+
compilerOptions: {
|
|
1385
|
+
...compilerOptions,
|
|
1386
|
+
jsx: "preserve",
|
|
1387
|
+
types: [...compilerOptions.types, "vite/client"],
|
|
1388
|
+
paths: {
|
|
1389
|
+
[`${defaults.appPrefix}/*`]: [`${rootDir}/../../*`],
|
|
1390
|
+
[`${defaults.srcPrefix}/*`]: [`${rootDir}/*`],
|
|
1391
|
+
[`${defaults.libPrefix}/*`]: [
|
|
1392
|
+
`${rootDir}/../../${defaults.libDir}/${sourceFolder}/*`
|
|
1393
|
+
]
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
};
|
|
1397
|
+
}
|
|
1398
|
+
return {
|
|
1399
|
+
include: [`${rootDir}/`, `${rootDir}/${defaults.libDir}/env.d.ts`],
|
|
1400
|
+
exclude: [
|
|
1401
|
+
`${rootDir}/${defaults.srcDir}/`,
|
|
1402
|
+
`${rootDir}/${defaults.libDir}/`
|
|
1403
|
+
],
|
|
1404
|
+
compilerOptions: {
|
|
1405
|
+
...compilerOptions,
|
|
1406
|
+
paths: {
|
|
1407
|
+
[`${defaults.appPrefix}/*`]: [`${rootDir}/*`]
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
};
|
|
1411
|
+
};
|
|
1412
|
+
|
|
1291
1413
|
// src/typebox.ts
|
|
1292
1414
|
var typeboxLiteralText = (text, sourceFolder) => {
|
|
1293
1415
|
const { refineTypeName = defaults.refineTypeName } = sourceFolder.config;
|
|
@@ -1304,26 +1426,40 @@ var typeboxLiteralText = (text, sourceFolder) => {
|
|
|
1304
1426
|
[new RegExp(`\\b${refineTypeName}\\s*<`, "g"), "Options<"]
|
|
1305
1427
|
].reduce((text2, [a, b]) => text2.replace(a, b), text);
|
|
1306
1428
|
};
|
|
1429
|
+
|
|
1430
|
+
// src/vite.ts
|
|
1431
|
+
import { builtinModules } from "node:module";
|
|
1432
|
+
var nodePrefix = () => {
|
|
1433
|
+
return {
|
|
1434
|
+
name: "kosmojs:node-prefix",
|
|
1435
|
+
enforce: "pre",
|
|
1436
|
+
resolveId(source) {
|
|
1437
|
+
return builtinModules.includes(source) ? { id: `node:${source}`, external: true } : void 0;
|
|
1438
|
+
}
|
|
1439
|
+
};
|
|
1440
|
+
};
|
|
1441
|
+
var vitePlugins = {
|
|
1442
|
+
nodePrefix
|
|
1443
|
+
};
|
|
1307
1444
|
export {
|
|
1308
1445
|
API_INDEX_BASENAME,
|
|
1309
1446
|
API_INDEX_PATTERN,
|
|
1310
1447
|
API_USE_BASENAME,
|
|
1311
1448
|
API_USE_PATTERN,
|
|
1312
|
-
GENERATOR_META,
|
|
1313
1449
|
PAGE_INDEX_BASENAME,
|
|
1314
1450
|
PAGE_INDEX_PATTERN,
|
|
1315
1451
|
PAGE_LAYOUT_BASENAME,
|
|
1316
1452
|
PAGE_LAYOUT_PATTERN,
|
|
1317
1453
|
astFactory,
|
|
1454
|
+
createHonoPattern,
|
|
1455
|
+
createPathPattern,
|
|
1318
1456
|
createRouteEntry,
|
|
1319
|
-
createTsconfigPaths,
|
|
1320
1457
|
defaults,
|
|
1321
1458
|
defineGenerator,
|
|
1322
1459
|
defineGeneratorFactory,
|
|
1323
|
-
|
|
1460
|
+
generateTsconfig,
|
|
1324
1461
|
isApiRoute,
|
|
1325
1462
|
isApiUse,
|
|
1326
|
-
isGenerator,
|
|
1327
1463
|
isPageLayout,
|
|
1328
1464
|
isPageRoute,
|
|
1329
1465
|
isRouteFile,
|
|
@@ -1334,13 +1470,13 @@ export {
|
|
|
1334
1470
|
pathTokensFactory,
|
|
1335
1471
|
render,
|
|
1336
1472
|
renderFactory,
|
|
1337
|
-
renderHelpers,
|
|
1338
1473
|
renderToFile,
|
|
1339
1474
|
routesFactory,
|
|
1340
1475
|
scanRoutes,
|
|
1341
1476
|
sortRoutes,
|
|
1342
1477
|
spinnerFactory,
|
|
1343
1478
|
typeboxLiteralText,
|
|
1479
|
+
vitePlugins,
|
|
1344
1480
|
withSpinner
|
|
1345
1481
|
};
|
|
1346
1482
|
//# sourceMappingURL=index.js.map
|