@ryusenkei/maezae 0.18.0 → 0.19.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/README.md +33 -1
- package/dist/analytics.js +30 -14
- package/dist/body.js +27 -22
- package/dist/client-ClY3gSSd.js +137 -0
- package/dist/delivery.js +1 -136
- package/dist/dev.js +9 -2
- package/dist/integrations.js +1 -1
- package/dist/model.js +128 -217
- package/dist/preview.js +1 -1
- package/dist/schema.d.ts +1 -0
- package/dist/schema.js +56 -0
- package/dist/{src-C6YqllXw.js → src-BMOqN7Xs.js} +3 -26
- package/dist/trace.js +1 -1
- package/dist/types/access/src/jwt.d.ts +6 -13
- package/dist/types/analytics/src/index.d.ts +2 -2
- package/dist/types/analytics/src/source.d.ts +0 -16
- package/dist/types/analytics/src/view.d.ts +24 -0
- package/dist/types/body/src/inline.d.ts +20 -0
- package/dist/types/body/src/normalize.d.ts +1 -3
- package/dist/types/cms-contract/src/index.d.ts +1 -1
- package/dist/types/cms-contract/src/roles.d.ts +3 -3
- package/dist/types/model/src/asset.d.ts +16 -0
- package/dist/types/model/src/index.d.ts +4 -3
- package/dist/types/model/src/mediaUrl.d.ts +2 -0
- package/dist/types/model/src/model.d.ts +1 -1
- package/dist/types/model/src/typesSource.d.ts +7 -0
- package/dist/types/{sdk/src/defaults.d.ts → platform/src/defaultModel.d.ts} +4 -1
- package/dist/types/sdk/src/analytics.d.ts +12 -2
- package/dist/types/sdk/src/delivery/index.d.ts +2 -2
- package/dist/types/sdk/src/delivery/values.d.ts +1 -17
- package/dist/types/sdk/src/model.d.ts +2 -2
- package/dist/types/sdk/src/schema.d.ts +5 -0
- package/dist/types/sdk/src/types-cli.d.ts +2 -0
- package/dist/types-cli.d.ts +1 -0
- package/dist/types-cli.js +7 -0
- package/dist/typesSource-BKPzvl--.js +62 -0
- package/package.json +8 -1
- package/dist/types/analytics/src/record.d.ts +0 -22
package/dist/model.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { c as coverStart, d as objectPosition, f as stillOf, i as acceptsRole, l as cropRect, m as isDateOnly, n as publicPathOf, o as typeOf, p as createClock, r as FIELD_ROLES, s as coverPosition, t as pagePathOf, u as croppedHotspot } from "./page-BnwHL-LC.js";
|
|
2
2
|
import { i as CORE_COMPONENTS, t as declaredComponentsSchema } from "./declared-Qo-mWnDd.js";
|
|
3
|
+
import { t as typesSourceOf } from "./typesSource-BKPzvl--.js";
|
|
3
4
|
import "./src-BrLwIWaT.js";
|
|
4
5
|
import { z } from "zod";
|
|
5
6
|
// ../model/src/asset.ts
|
|
@@ -511,6 +512,9 @@ const modelSchema = z.object({
|
|
|
511
512
|
/** コンテンツスキーマの JSON を検査して返却(形が合わなければ例外、理由は zod の issues) */
|
|
512
513
|
const parseModel = (json) => modelSchema.parse(normalizeLegacyModel(json));
|
|
513
514
|
// ../model/src/screens.ts
|
|
515
|
+
const TYPE_PREFIX = "type:";
|
|
516
|
+
/** メニュー項目の id(コンテンツタイプ) */
|
|
517
|
+
const typeItem = (type) => `${TYPE_PREFIX}${type}`;
|
|
514
518
|
/** メニューにある全項目の id(グループの中も、上から順) */
|
|
515
519
|
const menuItemsOf = (menu) => menu.flatMap((e) => typeof e === "string" ? [e] : e.items);
|
|
516
520
|
/** 編集画面に配置した項目の id(セクションの順) */
|
|
@@ -544,296 +548,203 @@ const parseScreens = (json) => screensSchema.parse(json);
|
|
|
544
548
|
// ../cms-contract/src/transfer.ts
|
|
545
549
|
/** スキーマと設定の形式の名前 */
|
|
546
550
|
const CONFIG_FORMAT = "cms-config";
|
|
547
|
-
// src/defaults.ts
|
|
548
551
|
/** 中立の既定のスキーマ(新しい媒体の作成で適用する型: post・author・tag・image・video、設定の移入の土台) */
|
|
549
|
-
const DEFAULT_SCHEMA = {
|
|
552
|
+
const DEFAULT_SCHEMA = { types: [
|
|
550
553
|
{
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
554
|
+
id: "post",
|
|
555
|
+
label: "投稿",
|
|
556
|
+
publishing: "review",
|
|
557
|
+
roles: {
|
|
558
|
+
title: "title",
|
|
559
|
+
image: "image",
|
|
560
|
+
body: "body"
|
|
558
561
|
},
|
|
559
|
-
|
|
562
|
+
fields: [
|
|
560
563
|
{
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
564
|
+
key: "title",
|
|
565
|
+
label: "タイトル",
|
|
566
|
+
type: "text",
|
|
567
|
+
required: "save"
|
|
565
568
|
},
|
|
566
569
|
{
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
570
|
+
key: "writers",
|
|
571
|
+
label: "著者",
|
|
572
|
+
type: "reference",
|
|
573
|
+
to: "author",
|
|
574
|
+
multiple: true
|
|
572
575
|
},
|
|
573
576
|
{
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
577
|
+
key: "image",
|
|
578
|
+
label: "メインの画像",
|
|
579
|
+
type: "media",
|
|
580
|
+
accept: ["image"]
|
|
578
581
|
},
|
|
579
582
|
{
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
583
|
+
key: "body",
|
|
584
|
+
label: "本文",
|
|
585
|
+
type: "body",
|
|
586
|
+
profile: {
|
|
587
|
+
headings: [
|
|
585
588
|
2,
|
|
586
589
|
3,
|
|
587
590
|
4
|
|
588
591
|
],
|
|
589
|
-
|
|
592
|
+
marks: [
|
|
590
593
|
"strong",
|
|
591
594
|
"em",
|
|
592
595
|
"code",
|
|
593
596
|
"strike"
|
|
594
597
|
],
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
+
list: {
|
|
599
|
+
ordered: true,
|
|
600
|
+
nested: true
|
|
598
601
|
},
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
+
quote: {
|
|
603
|
+
multiple: true,
|
|
604
|
+
cite: true
|
|
602
605
|
},
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
606
|
+
code: { caption: false },
|
|
607
|
+
table: {
|
|
608
|
+
head: "optional",
|
|
609
|
+
caption: "optional"
|
|
607
610
|
},
|
|
608
|
-
|
|
609
|
-
|
|
611
|
+
divider: true,
|
|
612
|
+
components: ["gallery", "link-card"]
|
|
610
613
|
}
|
|
611
614
|
},
|
|
612
615
|
{
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
+
key: "revised_at",
|
|
617
|
+
label: "更新日時",
|
|
618
|
+
type: "datetime"
|
|
616
619
|
},
|
|
617
620
|
{
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
621
|
+
key: "tags",
|
|
622
|
+
label: "タグ",
|
|
623
|
+
type: "reference",
|
|
624
|
+
to: "tag",
|
|
625
|
+
multiple: true
|
|
623
626
|
},
|
|
624
627
|
{
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
628
|
+
key: "excerpt",
|
|
629
|
+
label: "抜粋",
|
|
630
|
+
type: "textarea",
|
|
631
|
+
computed: {
|
|
632
|
+
kind: "excerpt",
|
|
633
|
+
from: "body"
|
|
631
634
|
}
|
|
632
635
|
},
|
|
633
636
|
{
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
637
|
+
key: "read_min",
|
|
638
|
+
label: "読了の分",
|
|
639
|
+
type: "number",
|
|
640
|
+
computed: {
|
|
641
|
+
kind: "read_min",
|
|
642
|
+
from: "body"
|
|
640
643
|
}
|
|
641
644
|
},
|
|
642
645
|
{
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
646
|
+
key: "links",
|
|
647
|
+
label: "リンク先",
|
|
648
|
+
type: "text",
|
|
649
|
+
multiple: true,
|
|
650
|
+
computed: {
|
|
651
|
+
kind: "links",
|
|
652
|
+
from: "body"
|
|
650
653
|
}
|
|
651
654
|
}
|
|
652
655
|
],
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
656
|
+
pages: [{
|
|
657
|
+
path: "/posts/{id}",
|
|
658
|
+
public: [{
|
|
659
|
+
key: "status",
|
|
660
|
+
in: ["published"]
|
|
658
661
|
}, {
|
|
659
|
-
|
|
660
|
-
|
|
662
|
+
key: "published_at",
|
|
663
|
+
notFuture: true
|
|
661
664
|
}]
|
|
662
665
|
}]
|
|
663
666
|
},
|
|
664
667
|
{
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
668
|
+
id: "author",
|
|
669
|
+
label: "著者",
|
|
670
|
+
roles: {
|
|
671
|
+
title: "name",
|
|
672
|
+
image: "portrait"
|
|
670
673
|
},
|
|
671
|
-
|
|
674
|
+
fields: [
|
|
672
675
|
{
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
676
|
+
key: "name",
|
|
677
|
+
label: "名前",
|
|
678
|
+
type: "text",
|
|
679
|
+
required: "save"
|
|
677
680
|
},
|
|
678
681
|
{
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
+
key: "bio",
|
|
683
|
+
label: "紹介",
|
|
684
|
+
type: "textarea"
|
|
682
685
|
},
|
|
683
686
|
{
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
687
|
+
key: "portrait",
|
|
688
|
+
label: "顔の画像",
|
|
689
|
+
type: "media",
|
|
690
|
+
accept: ["image"]
|
|
688
691
|
}
|
|
689
692
|
],
|
|
690
|
-
|
|
693
|
+
pages: [{ path: "/authors/{id}" }]
|
|
691
694
|
},
|
|
692
695
|
{
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
696
|
+
id: "tag",
|
|
697
|
+
label: "タグ",
|
|
698
|
+
roles: { title: "label" },
|
|
699
|
+
fields: [{
|
|
700
|
+
key: "label",
|
|
701
|
+
label: "名前",
|
|
702
|
+
type: "text",
|
|
703
|
+
required: "save"
|
|
701
704
|
}]
|
|
702
705
|
},
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
"label": "画像",
|
|
706
|
-
"description": "見せたい点(hotspot)と切り抜き(crop)を画像ごとに1つ保持、切り抜く場所すべてで共通",
|
|
707
|
-
"fields": [
|
|
708
|
-
{
|
|
709
|
-
"key": "mime_type",
|
|
710
|
-
"label": "形式",
|
|
711
|
-
"type": "text",
|
|
712
|
-
"required": "save",
|
|
713
|
-
"description": "MIME タイプ"
|
|
714
|
-
},
|
|
715
|
-
{
|
|
716
|
-
"key": "size",
|
|
717
|
-
"label": "サイズ",
|
|
718
|
-
"type": "number",
|
|
719
|
-
"required": "save",
|
|
720
|
-
"description": "バイト数"
|
|
721
|
-
},
|
|
722
|
-
{
|
|
723
|
-
"key": "width",
|
|
724
|
-
"label": "幅",
|
|
725
|
-
"type": "number",
|
|
726
|
-
"required": "save",
|
|
727
|
-
"description": "px"
|
|
728
|
-
},
|
|
729
|
-
{
|
|
730
|
-
"key": "height",
|
|
731
|
-
"label": "高さ",
|
|
732
|
-
"type": "number",
|
|
733
|
-
"required": "save",
|
|
734
|
-
"description": "px"
|
|
735
|
-
},
|
|
736
|
-
{
|
|
737
|
-
"key": "alt",
|
|
738
|
-
"label": "代替テキスト",
|
|
739
|
-
"type": "text",
|
|
740
|
-
"description": "使用する側の既定の値、使用する場所ごとに上書き可"
|
|
741
|
-
}
|
|
742
|
-
]
|
|
743
|
-
},
|
|
744
|
-
{
|
|
745
|
-
"id": "video",
|
|
746
|
-
"label": "動画",
|
|
747
|
-
"fields": [
|
|
748
|
-
{
|
|
749
|
-
"key": "mime_type",
|
|
750
|
-
"label": "形式",
|
|
751
|
-
"type": "text",
|
|
752
|
-
"required": "save",
|
|
753
|
-
"description": "MIME タイプ"
|
|
754
|
-
},
|
|
755
|
-
{
|
|
756
|
-
"key": "size",
|
|
757
|
-
"label": "サイズ",
|
|
758
|
-
"type": "number",
|
|
759
|
-
"required": "save",
|
|
760
|
-
"description": "バイト数"
|
|
761
|
-
},
|
|
762
|
-
{
|
|
763
|
-
"key": "width",
|
|
764
|
-
"label": "幅",
|
|
765
|
-
"type": "number",
|
|
766
|
-
"required": "save",
|
|
767
|
-
"description": "px"
|
|
768
|
-
},
|
|
769
|
-
{
|
|
770
|
-
"key": "height",
|
|
771
|
-
"label": "高さ",
|
|
772
|
-
"type": "number",
|
|
773
|
-
"required": "save",
|
|
774
|
-
"description": "px"
|
|
775
|
-
},
|
|
776
|
-
{
|
|
777
|
-
"key": "alt",
|
|
778
|
-
"label": "代替テキスト",
|
|
779
|
-
"type": "text",
|
|
780
|
-
"description": "使用する側の既定の値、使用する場所ごとに上書き可"
|
|
781
|
-
},
|
|
782
|
-
{
|
|
783
|
-
"key": "duration",
|
|
784
|
-
"label": "長さ",
|
|
785
|
-
"type": "number",
|
|
786
|
-
"description": "秒"
|
|
787
|
-
},
|
|
788
|
-
{
|
|
789
|
-
"key": "poster",
|
|
790
|
-
"label": "ポスター画像",
|
|
791
|
-
"type": "media",
|
|
792
|
-
"accept": ["image"],
|
|
793
|
-
"description": "読み込み前・動きを抑える設定・OG で代わりに表示"
|
|
794
|
-
}
|
|
795
|
-
]
|
|
796
|
-
}
|
|
706
|
+
IMAGE_TYPE,
|
|
707
|
+
VIDEO_TYPE
|
|
797
708
|
] };
|
|
798
709
|
/** 既定の画面設定(新しい媒体の作成で適用する中立の値、移入する screens の土台) */
|
|
799
710
|
const DEFAULT_SCREENS = {
|
|
800
|
-
|
|
711
|
+
menu: [
|
|
801
712
|
"dashboard",
|
|
802
713
|
"calendar",
|
|
803
714
|
{
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
715
|
+
id: "content",
|
|
716
|
+
label: "コンテンツ",
|
|
717
|
+
items: [typeItem("post"), "media"]
|
|
807
718
|
},
|
|
808
719
|
{
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
720
|
+
id: "masters",
|
|
721
|
+
label: "マスタ",
|
|
722
|
+
items: [typeItem("tag"), typeItem("author")]
|
|
812
723
|
}
|
|
813
724
|
],
|
|
814
|
-
|
|
725
|
+
editors: { post: { sections: [
|
|
815
726
|
{
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
727
|
+
id: "classify",
|
|
728
|
+
label: "分類",
|
|
729
|
+
items: ["writers", "tags"]
|
|
819
730
|
},
|
|
820
731
|
{
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
732
|
+
id: "publish",
|
|
733
|
+
label: "公開",
|
|
734
|
+
items: ["published_at", "revised_at"]
|
|
824
735
|
},
|
|
825
736
|
{
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
737
|
+
id: "excerpt",
|
|
738
|
+
label: "説明",
|
|
739
|
+
items: ["excerpt"]
|
|
829
740
|
},
|
|
830
741
|
{
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
742
|
+
id: "image",
|
|
743
|
+
label: "メインの画像",
|
|
744
|
+
items: ["image"]
|
|
834
745
|
}
|
|
835
746
|
] } },
|
|
836
|
-
|
|
747
|
+
columns: { post: [
|
|
837
748
|
"status",
|
|
838
749
|
"writers",
|
|
839
750
|
"assignee",
|
|
@@ -841,4 +752,4 @@ const DEFAULT_SCREENS = {
|
|
|
841
752
|
"updated_at"
|
|
842
753
|
] }
|
|
843
754
|
};
|
|
844
|
-
export { CONFIG_FORMAT, DEFAULT_SCHEMA, DEFAULT_SCREENS, IMAGE_TYPE, VIDEO_TYPE, coverPosition, coverStart, createClock, cropRect, croppedHotspot, isDateOnly, mediaSchema, objectPosition, pagePathOf, parseModel, parseScreens, publicPathOf, stillOf, typeOf };
|
|
755
|
+
export { CONFIG_FORMAT, DEFAULT_SCHEMA, DEFAULT_SCREENS, IMAGE_TYPE, VIDEO_TYPE, coverPosition, coverStart, createClock, cropRect, croppedHotspot, isDateOnly, mediaSchema, objectPosition, pagePathOf, parseModel, parseScreens, publicPathOf, stillOf, typeOf, typesSourceOf };
|
package/dist/preview.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { i as SIGNED_HEADERS, o as signParts, s as signedHeaders, c as verifyParts, l as verifyRequest } from "./src-
|
|
1
|
+
export { i as SIGNED_HEADERS, o as signParts, s as signedHeaders, c as verifyParts, l as verifyRequest } from "./src-BMOqN7Xs.js";
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './types/sdk/src/schema.js';
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { t as typesSourceOf } from "./typesSource-BKPzvl--.js";
|
|
2
|
+
import { t as DELIVERY_PATH } from "./client-ClY3gSSd.js";
|
|
3
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
4
|
+
// src/schema.ts
|
|
5
|
+
/** 標準出力と標準エラーの文 */
|
|
6
|
+
const MESSAGES = {
|
|
7
|
+
usage: "usage: maezae-types --out <file> [--check] [--url <delivery API URL>](API key: MAEZAE_API_KEY)",
|
|
8
|
+
missingUrl: "missing_url: --url か MAEZAE_DELIVERY_URL に配信 API の URL(例: https://example.com/<媒体>)",
|
|
9
|
+
missingKey: "missing_api_key: 環境変数 MAEZAE_API_KEY",
|
|
10
|
+
fetchFailed: (status, body) => `fetch_failed: ${status} ${body.slice(0, 200)}`,
|
|
11
|
+
drift: (file) => `schema_drift: ${file} が CMS のスキーマと違う(maezae-types --out ${file} で生成し直す)`,
|
|
12
|
+
upToDate: (file) => `up_to_date: ${file}`,
|
|
13
|
+
written: (file) => `written: ${file}`
|
|
14
|
+
};
|
|
15
|
+
/** 引数(--name value と --flag) */
|
|
16
|
+
function argsOf(argv) {
|
|
17
|
+
const value = (name) => {
|
|
18
|
+
const i = argv.indexOf(name);
|
|
19
|
+
return i >= 0 ? argv[i + 1] : void 0;
|
|
20
|
+
};
|
|
21
|
+
return {
|
|
22
|
+
out: value("--out"),
|
|
23
|
+
url: value("--url"),
|
|
24
|
+
check: argv.includes("--check")
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** 配信 API の型の一覧(/types、表示名・選択肢・上限・ページの URL の形を含む。実行時に読む値もここから) */
|
|
28
|
+
async function fetchDeliveredTypes(url, apiKey, fetcher = fetch) {
|
|
29
|
+
const res = await fetcher(`${url.replace(/\/+$/, "")}${DELIVERY_PATH}/types`, { headers: { authorization: `Bearer ${apiKey}` } });
|
|
30
|
+
if (!res.ok) throw new Error(MESSAGES.fetchFailed(res.status, await res.text().catch(() => "")));
|
|
31
|
+
return (await res.json()).types;
|
|
32
|
+
}
|
|
33
|
+
/** CLI の本体(戻り値は終了の状態) */
|
|
34
|
+
async function runTypesCli(argv, env, fetcher = fetch) {
|
|
35
|
+
const { out, url = env.MAEZAE_DELIVERY_URL, check } = argsOf(argv);
|
|
36
|
+
if (!out) return console.error(MESSAGES.usage), 1;
|
|
37
|
+
if (!url) return console.error(MESSAGES.missingUrl), 1;
|
|
38
|
+
const apiKey = env.MAEZAE_API_KEY;
|
|
39
|
+
if (!apiKey) return console.error(MESSAGES.missingKey), 1;
|
|
40
|
+
const source = typesSourceOf({ types: await fetchDeliveredTypes(url, apiKey, fetcher) });
|
|
41
|
+
if (check) {
|
|
42
|
+
let current = null;
|
|
43
|
+
try {
|
|
44
|
+
current = readFileSync(out, "utf8").replace(/\r\n/g, "\n");
|
|
45
|
+
} catch {
|
|
46
|
+
current = null;
|
|
47
|
+
}
|
|
48
|
+
if (current !== source) return console.error(MESSAGES.drift(out)), 1;
|
|
49
|
+
console.log(MESSAGES.upToDate(out));
|
|
50
|
+
return 0;
|
|
51
|
+
}
|
|
52
|
+
writeFileSync(out, source);
|
|
53
|
+
console.log(MESSAGES.written(out));
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
export { fetchDeliveredTypes, runTypesCli };
|
|
@@ -1,32 +1,9 @@
|
|
|
1
|
-
// ../access/src/jwt.ts
|
|
2
|
-
const CERTS_TTL_MS = 3e5;
|
|
3
|
-
const REFRESH_INTERVAL_MS = 3e4;
|
|
4
|
-
/** 公開鍵の一覧を保持する取得(取得の失敗は保持しない) */
|
|
5
|
-
function cachedCerts(fetcher, clock = Date.now) {
|
|
6
|
-
const cache = /* @__PURE__ */ new Map();
|
|
7
|
-
return async (url, refresh = false) => {
|
|
8
|
-
const hit = cache.get(url);
|
|
9
|
-
const age = hit ? clock() - hit.at : Infinity;
|
|
10
|
-
if (hit && age < (refresh ? REFRESH_INTERVAL_MS : CERTS_TTL_MS)) return hit;
|
|
11
|
-
const fresh = await fetcher(url);
|
|
12
|
-
cache.set(url, {
|
|
13
|
-
keys: fresh.keys,
|
|
14
|
-
at: clock()
|
|
15
|
-
});
|
|
16
|
-
return fresh;
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
cachedCerts(async (url) => {
|
|
20
|
-
const res = await fetch(url);
|
|
21
|
-
if (!res.ok) throw new Error(`JWKS の取得に失敗(${res.status})`);
|
|
22
|
-
return res.json();
|
|
23
|
-
});
|
|
24
|
-
/** base64url の復号 */
|
|
25
|
-
const decodeBase64Url = (s) => Uint8Array.from(atob(s.replace(/-/g, "+").replace(/_/g, "/").padEnd(Math.ceil(s.length / 4) * 4, "=")), (c) => c.charCodeAt(0));
|
|
26
1
|
// ../access/src/signed.ts
|
|
27
2
|
const enc = new TextEncoder();
|
|
28
3
|
/** 既定で許す時刻のずれ(秒) */
|
|
29
4
|
const MAX_SKEW_SEC = 300;
|
|
5
|
+
/** base64url の復号 */
|
|
6
|
+
const decodeBase64Url = (s) => Uint8Array.from(atob(s.replace(/-/g, "+").replace(/_/g, "/").padEnd(Math.ceil(s.length / 4) * 4, "=")), (c) => c.charCodeAt(0));
|
|
30
7
|
/** 経路ごとのヘッダーの名前(署名と主体) */
|
|
31
8
|
const SIGNED_HEADERS = {
|
|
32
9
|
/** MCP → CMS の署名(鍵は MCP_TOKEN) */
|
|
@@ -195,7 +172,7 @@ function startEdgeSpan({ name, request, sampleRate = 1, write = (line) => consol
|
|
|
195
172
|
};
|
|
196
173
|
write(JSON.stringify({
|
|
197
174
|
level: "info",
|
|
198
|
-
|
|
175
|
+
event: "span",
|
|
199
176
|
...span
|
|
200
177
|
}));
|
|
201
178
|
}
|
package/dist/trace.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { r as TRACEPARENT_HEADER, t as sampleRateOf, n as withEdgeSpan } from "./src-
|
|
1
|
+
export { r as TRACEPARENT_HEADER, t as sampleRateOf, n as withEdgeSpan } from "./src-BMOqN7Xs.js";
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
type Jwk = JsonWebKey & {
|
|
2
|
-
kid?: string;
|
|
3
|
-
};
|
|
4
|
-
/** 公開鍵の一覧の取得(引数は JWKS の URL、refresh は保持した値を使用せずに再取得、テストで差し替え) */
|
|
5
|
-
export type FetchCerts = (jwksUrl: string, refresh?: boolean) => Promise<{
|
|
6
|
-
keys: Jwk[];
|
|
7
|
-
}>;
|
|
8
1
|
/** JWT のクレーム(検証を通った値) */
|
|
9
2
|
export type JwtClaims = Readonly<Record<string, unknown>>;
|
|
3
|
+
/** 公開鍵の一覧の取得の差し替え(テスト用、引数は JWKS の URL) */
|
|
4
|
+
export type FetchCerts = (jwksUrl: string) => Promise<{
|
|
5
|
+
keys: JsonWebKey[];
|
|
6
|
+
}>;
|
|
10
7
|
/** JWT の検証の設定 */
|
|
11
8
|
export type JwtOptions = Readonly<{
|
|
12
9
|
/** 発行元(iss と完全に一致) */
|
|
@@ -15,15 +12,12 @@ export type JwtOptions = Readonly<{
|
|
|
15
12
|
audience: string | readonly string[];
|
|
16
13
|
/** 公開鍵の一覧の URL */
|
|
17
14
|
jwksUrl: string;
|
|
15
|
+
/** 現在時刻(ミリ秒、テスト用) */
|
|
18
16
|
now?: number;
|
|
19
17
|
certs?: FetchCerts;
|
|
20
18
|
}>;
|
|
21
|
-
/** 公開鍵の一覧を保持する取得(取得の失敗は保持しない) */
|
|
22
|
-
export declare function cachedCerts(fetcher: FetchCerts, clock?: () => number): FetchCerts;
|
|
23
|
-
/** base64url の復号 */
|
|
24
|
-
export declare const decodeBase64Url: (s: string) => Uint8Array<ArrayBuffer>;
|
|
25
19
|
/** 検証を通った JWT のクレーム(署名・発行元・宛先・期限のどれかが違えば null) */
|
|
26
|
-
export declare function verifyJwt(token: string,
|
|
20
|
+
export declare function verifyJwt(token: string, options: JwtOptions): Promise<JwtClaims | null>;
|
|
27
21
|
/**
|
|
28
22
|
* Cloudflare Access の JWT を検証する設定(teamDomain は <チーム>.cloudflareaccess.com、aud はアプリの AUD)
|
|
29
23
|
* - aud: カンマ区切りで複数のアプリ(ホスト名ごとにアプリが分かれる管理画面、どのアプリを通すかは Access がホスト名で判定)
|
|
@@ -39,4 +33,3 @@ export declare function verifyAccessJwt(token: string, { teamDomain, aud, now, c
|
|
|
39
33
|
now?: number;
|
|
40
34
|
certs?: FetchCerts;
|
|
41
35
|
}): Promise<string | null>;
|
|
42
|
-
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { type Classify, VIEW_COLUMNS, type ViewEvent, viewOf, type ViewOptions } from './view.js';
|
|
2
2
|
export { syncCron } from './schedule.js';
|
|
3
3
|
export { isViewsCron, sharedViews, viewsFor, viewsSince, viewsSyncOf } from './shared.js';
|
|
4
|
-
export {
|
|
4
|
+
export { type DailyRow, fixedSource, type ProjectSource, renamedSource, type Source } from './source.js';
|
|
5
5
|
export { readDaily, syncDaily } from './store.js';
|
|
@@ -9,27 +9,11 @@ export type DailyRow = {
|
|
|
9
9
|
export type Source = {
|
|
10
10
|
daily(since: string): Promise<DailyRow[]>;
|
|
11
11
|
};
|
|
12
|
-
/** Analytics Engine の接続の設定(token は Account Analytics の読み取りの API トークン、project は絞り込む媒体の識別子) */
|
|
13
|
-
type AnalyticsEngineOptions = {
|
|
14
|
-
accountId: string;
|
|
15
|
-
token: string;
|
|
16
|
-
dataset: string;
|
|
17
|
-
project?: string;
|
|
18
|
-
};
|
|
19
|
-
/** 1回の問い合わせの行数 */
|
|
20
|
-
export declare const PAGE_ROWS = 10000;
|
|
21
|
-
/** 問い合わせの回数の上限(PAGE_ROWS との積が1回で集計できる行数) */
|
|
22
|
-
export declare const MAX_PAGES = 20;
|
|
23
|
-
/** Analytics Engine の SQL API の読み込み元 */
|
|
24
|
-
export declare function analyticsEngine({ accountId, token, dataset, project }: AnalyticsEngineOptions): Source;
|
|
25
12
|
/** 全媒体の読み込み元の型(since 以降の日付の閲覧数を媒体の識別子ごとに) */
|
|
26
13
|
export type ProjectSource = {
|
|
27
14
|
dailyByProject(since: string): Promise<ReadonlyMap<string, DailyRow[]>>;
|
|
28
15
|
};
|
|
29
|
-
/** 全媒体を1回の問い合わせで集計する Analytics Engine の読み込み元(媒体の列が空の記録は除外) */
|
|
30
|
-
export declare function projectDaily(options: Omit<AnalyticsEngineOptions, 'project'>): ProjectSource;
|
|
31
16
|
/** 集計済みの行の読み込み元(定期の集計で全媒体の問い合わせ結果を媒体ごとに受け渡し、daily は since 以降の行) */
|
|
32
17
|
export declare const fixedSource: (rows: readonly DailyRow[]) => Source;
|
|
33
18
|
/** 種類を付け替えた読み込み元(renames は旧の種類 → 今の種類、付け替えで重なった行は閲覧数を合計) */
|
|
34
19
|
export declare function renamedSource(source: Source, renames: Readonly<Record<string, string>>): Source;
|
|
35
|
-
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** パスから種類と ID への対応(利用側が定義、例: /articles/<id> は記事) */
|
|
2
|
+
export type Classify = (path: string) => {
|
|
3
|
+
kind: string;
|
|
4
|
+
id: string;
|
|
5
|
+
};
|
|
6
|
+
/** 閲覧の出来事(project は媒体の識別子) */
|
|
7
|
+
export type ViewEvent = Readonly<{
|
|
8
|
+
kind: string;
|
|
9
|
+
id: string;
|
|
10
|
+
path: string;
|
|
11
|
+
date: string;
|
|
12
|
+
event: 'view';
|
|
13
|
+
project?: string;
|
|
14
|
+
}>;
|
|
15
|
+
/** 位置で持つ記録先の列の順 */
|
|
16
|
+
export declare const VIEW_COLUMNS: readonly ["kind", "id", "path", "date", "event", "project"];
|
|
17
|
+
/** 出来事にする設定(project は媒体の識別子) */
|
|
18
|
+
export type ViewOptions = Readonly<{
|
|
19
|
+
classify: Classify;
|
|
20
|
+
timeZone: string;
|
|
21
|
+
project?: string;
|
|
22
|
+
}>;
|
|
23
|
+
/** 閲覧の出来事(対象: GET で応答が200の HTML・ボット以外、ほかは null) */
|
|
24
|
+
export declare function viewOf(request: Request, response: Response, { classify, timeZone, project }: ViewOptions): ViewEvent | null;
|