@ablogcms/url 3.2.28-beta.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 +24 -0
- package/dist/acms.d.ts +16 -0
- package/dist/acms.mjs +1 -0
- package/dist/acms.mjs.map +1 -0
- package/dist/acmsField.d.ts +13 -0
- package/dist/acmsField.mjs +9 -0
- package/dist/acmsField.mjs.map +1 -0
- package/dist/acmsLink.d.ts +44 -0
- package/dist/acmsLink.mjs +81 -0
- package/dist/acmsLink.mjs.map +1 -0
- package/dist/acmsPath.d.ts +2 -0
- package/dist/acmsPath.mjs +9 -0
- package/dist/acmsPath.mjs.map +1 -0
- package/dist/chunk-GHGJBKQU.mjs +192 -0
- package/dist/chunk-GHGJBKQU.mjs.map +1 -0
- package/dist/chunk-HZZTSXXP.mjs +226 -0
- package/dist/chunk-HZZTSXXP.mjs.map +1 -0
- package/dist/chunk-OJI2ZTVL.mjs +23 -0
- package/dist/chunk-OJI2ZTVL.mjs.map +1 -0
- package/dist/chunk-OUKSKSZA.mjs +295 -0
- package/dist/chunk-OUKSKSZA.mjs.map +1 -0
- package/dist/chunk-PHGYMRZK.mjs +22 -0
- package/dist/chunk-PHGYMRZK.mjs.map +1 -0
- package/dist/chunk-XTN64CHF.mjs +73 -0
- package/dist/chunk-XTN64CHF.mjs.map +1 -0
- package/dist/chunk-ZDAAXRTI.mjs +43 -0
- package/dist/chunk-ZDAAXRTI.mjs.map +1 -0
- package/dist/createAcmsContextFromFormData.d.ts +5 -0
- package/dist/createAcmsContextFromFormData.mjs +63 -0
- package/dist/createAcmsContextFromFormData.mjs.map +1 -0
- package/dist/createAcmsPathHelper.d.ts +9 -0
- package/dist/createAcmsPathHelper.mjs +13 -0
- package/dist/createAcmsPathHelper.mjs.map +1 -0
- package/dist/defaults.d.ts +17 -0
- package/dist/defaults.mjs +7 -0
- package/dist/defaults.mjs.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.mjs +43 -0
- package/dist/index.mjs.map +1 -0
- package/dist/parseAcmsPath.d.ts +2 -0
- package/dist/parseAcmsPath.mjs +11 -0
- package/dist/parseAcmsPath.mjs.map +1 -0
- package/dist/types.d.ts +105 -0
- package/dist/types.mjs +15 -0
- package/dist/types.mjs.map +1 -0
- package/dist/utils.d.ts +11 -0
- package/dist/utils.mjs +11 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +90 -0
package/README.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# @ablogcms/url
|
|
2
|
+
|
|
3
|
+
a-blog cms の URL 生成・パース・パス規約ヘルパーを提供するパッケージ。
|
|
4
|
+
|
|
5
|
+
## 使い方
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { acmsPath, parseAcmsPath, AcmsFieldList } from '@ablogcms/url';
|
|
9
|
+
|
|
10
|
+
const path = acmsPath({ bid: 1, cid: 2 }); // 'bid/1/cid/2/'
|
|
11
|
+
const context = parseAcmsPath(path);
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
- `acmsPath(context)`: URL パス規約(`bid/1/cid/2/...` 形式)を組み立てる。
|
|
15
|
+
- `parseAcmsPath(path)`: パスをパースして `AcmsContext` に変換する。
|
|
16
|
+
- `createAcmsPathHelper(...)`: `acmsPath` / `parseAcmsPath` を特定のセグメント構成に束縛したヘルパーを作る。
|
|
17
|
+
- `AcmsFieldList`: フィールド絞り込みクエリを表現する。
|
|
18
|
+
|
|
19
|
+
追加のヘルパーは sub-path から import する。
|
|
20
|
+
|
|
21
|
+
| sub-path | 内容 |
|
|
22
|
+
|---|---|
|
|
23
|
+
| `./acms-link` | `ACMS.Config` / `ACMS.Library.acmsPath` に依存する `acmsLink` を組み立てる `createAcmsLink` |
|
|
24
|
+
| `./create-acms-context-from-form-data` | フォーム送信データから `AcmsContext` を組み立てる |
|
package/dist/acms.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type acmsPath from './acmsPath.js';
|
|
2
|
+
import type parseAcmsPath from './parseAcmsPath.js';
|
|
3
|
+
import type { AcmsLink } from './acmsLink.js';
|
|
4
|
+
import type createAcmsContextFromFormData from './createAcmsContextFromFormData.js';
|
|
5
|
+
import type { AcmsPathSegments } from './types.js';
|
|
6
|
+
declare module '@ablogcms/types/acms' {
|
|
7
|
+
interface AcmsLibrary {
|
|
8
|
+
acmsPath: typeof acmsPath;
|
|
9
|
+
parseAcmsPath: typeof parseAcmsPath;
|
|
10
|
+
acmsLink: AcmsLink;
|
|
11
|
+
createAcmsContextFromFormData: typeof createAcmsContextFromFormData;
|
|
12
|
+
}
|
|
13
|
+
interface AcmsConfig {
|
|
14
|
+
segments: AcmsPathSegments;
|
|
15
|
+
}
|
|
16
|
+
}
|
package/dist/acms.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=acms.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type AcmsField } from './types.js';
|
|
2
|
+
export default class AcmsFieldList {
|
|
3
|
+
private fields;
|
|
4
|
+
constructor(fields?: AcmsField[]);
|
|
5
|
+
push(field: AcmsField): void;
|
|
6
|
+
pop(): AcmsField | undefined;
|
|
7
|
+
shift(): AcmsField | undefined;
|
|
8
|
+
unshift(field: AcmsField): void;
|
|
9
|
+
getFields(): AcmsField[];
|
|
10
|
+
toString(): string;
|
|
11
|
+
static fromString(input: string): AcmsFieldList;
|
|
12
|
+
static fromFormData(formData: FormData): AcmsFieldList;
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Weaken } from '@ablogcms/types/utils';
|
|
2
|
+
import type { AcmsContextWithSearchParams } from './types.js';
|
|
3
|
+
export interface AcmsLinkContext extends Weaken<AcmsContextWithSearchParams, 'bid' | 'cid' | 'eid' | 'uid' | 'tag' | 'date'> {
|
|
4
|
+
bid?: AcmsContextWithSearchParams['bid'] | string;
|
|
5
|
+
cid?: AcmsContextWithSearchParams['cid'] | string;
|
|
6
|
+
eid?: AcmsContextWithSearchParams['eid'] | string;
|
|
7
|
+
uid?: AcmsContextWithSearchParams['uid'] | string;
|
|
8
|
+
tag?: AcmsContextWithSearchParams['tag'] | string;
|
|
9
|
+
date?: AcmsContextWithSearchParams['date'] | string;
|
|
10
|
+
Query?: Record<string, any>;
|
|
11
|
+
}
|
|
12
|
+
interface AcmsLinkOptions {
|
|
13
|
+
/**
|
|
14
|
+
* 現在のURLコンテキストを継承するかどうか
|
|
15
|
+
* デフォルト: false
|
|
16
|
+
*/
|
|
17
|
+
inherit: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* tplコンテキストがajaxから始まる場合キャッシュバスティングようのクエリを自動で付与するかどうか
|
|
20
|
+
* デフォルト: true
|
|
21
|
+
*/
|
|
22
|
+
ajaxCacheBusting: boolean;
|
|
23
|
+
}
|
|
24
|
+
/** acmsLink が必要とする Config の最小サブセット(ACMS.Config 全体に依存しない) */
|
|
25
|
+
export interface AcmsLinkConfig {
|
|
26
|
+
scriptRoot: string;
|
|
27
|
+
bid?: string;
|
|
28
|
+
cid?: string;
|
|
29
|
+
eid?: string;
|
|
30
|
+
admin?: string;
|
|
31
|
+
keyword?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface AcmsLinkDeps {
|
|
34
|
+
/** コール時評価を維持するためアクセサで受ける(生成時キャプチャすると Config の実行時書き換えに追従できない) */
|
|
35
|
+
getConfig: () => AcmsLinkConfig;
|
|
36
|
+
/** createAcmsPathHelper(segments) が返す acmsPath */
|
|
37
|
+
acmsPath: (context: AcmsContextWithSearchParams) => string;
|
|
38
|
+
}
|
|
39
|
+
export type AcmsLink = (context: AcmsLinkContext, options?: boolean | Partial<AcmsLinkOptions>) => string;
|
|
40
|
+
/**
|
|
41
|
+
* acmsLink
|
|
42
|
+
*/
|
|
43
|
+
export declare function createAcmsLink({ getConfig, acmsPath }: AcmsLinkDeps): AcmsLink;
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// src/acmsLink.ts
|
|
2
|
+
import { parseUrlSearchParams } from "@ablogcms/utils";
|
|
3
|
+
var defaultOptions = {
|
|
4
|
+
inherit: false,
|
|
5
|
+
ajaxCacheBusting: true
|
|
6
|
+
};
|
|
7
|
+
function toAcmsContext(context, options) {
|
|
8
|
+
const bid = typeof context.bid === "string" ? parseInt(context.bid, 10) : context.bid;
|
|
9
|
+
const cid = typeof context.cid === "string" ? parseInt(context.cid, 10) : context.cid;
|
|
10
|
+
const eid = typeof context.eid === "string" ? parseInt(context.eid, 10) : context.eid;
|
|
11
|
+
const uid = typeof context.uid === "string" ? parseInt(context.uid, 10) : context.uid;
|
|
12
|
+
const tag = typeof context.tag === "string" ? context.tag.split("/") : context.tag;
|
|
13
|
+
let { date } = context;
|
|
14
|
+
if (typeof date === "string") {
|
|
15
|
+
const [year, month, day] = date.split("/").map((v) => parseInt(v, 10));
|
|
16
|
+
if (year !== void 0 && !isNaN(year)) {
|
|
17
|
+
date = { year };
|
|
18
|
+
if (month !== void 0 && !isNaN(month)) {
|
|
19
|
+
date.month = month;
|
|
20
|
+
if (day !== void 0 && !isNaN(day)) {
|
|
21
|
+
date.day = day;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
} else {
|
|
25
|
+
date = void 0;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const _searchParams = context.searchParams || context.Query;
|
|
29
|
+
const { Query: _, ...inheritContext } = context;
|
|
30
|
+
let searchParams = _searchParams instanceof URLSearchParams ? parseUrlSearchParams(_searchParams) : _searchParams;
|
|
31
|
+
if (options.ajaxCacheBusting && context.tpl && /^ajax\//.test(context.tpl)) {
|
|
32
|
+
searchParams = {
|
|
33
|
+
...searchParams,
|
|
34
|
+
v: Date.now().toString()
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
return {
|
|
38
|
+
...inheritContext,
|
|
39
|
+
bid,
|
|
40
|
+
cid,
|
|
41
|
+
eid,
|
|
42
|
+
uid,
|
|
43
|
+
tag,
|
|
44
|
+
date,
|
|
45
|
+
searchParams
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function createAcmsLink({ getConfig, acmsPath }) {
|
|
49
|
+
return function acmsLink(context, options = {}) {
|
|
50
|
+
const _options = typeof options === "boolean" ? { inherit: options } : options;
|
|
51
|
+
const config = { ...defaultOptions, ..._options };
|
|
52
|
+
const Config = getConfig();
|
|
53
|
+
function empty(value) {
|
|
54
|
+
return typeof value === "undefined" || value === null;
|
|
55
|
+
}
|
|
56
|
+
if (config.inherit) {
|
|
57
|
+
if (empty(context.cid)) {
|
|
58
|
+
context.cid = Config.cid;
|
|
59
|
+
}
|
|
60
|
+
if (empty(context.eid)) {
|
|
61
|
+
context.eid = Config.eid;
|
|
62
|
+
}
|
|
63
|
+
if (empty(context.admin)) {
|
|
64
|
+
context.admin = Config.admin;
|
|
65
|
+
}
|
|
66
|
+
if (empty(context.keyword)) {
|
|
67
|
+
context.keyword = Config.keyword;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (empty(context.bid) || context.bid === "") {
|
|
71
|
+
context.bid = Config.bid;
|
|
72
|
+
}
|
|
73
|
+
let url = Config.scriptRoot;
|
|
74
|
+
url += acmsPath(toAcmsContext(context, config));
|
|
75
|
+
return url;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export {
|
|
79
|
+
createAcmsLink
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=acmsLink.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/acmsLink.ts"],"sourcesContent":["import { Weaken } from '@ablogcms/types/utils';\nimport { parseUrlSearchParams } from '@ablogcms/utils';\nimport type { AcmsContextWithSearchParams } from './types';\n\nexport interface AcmsLinkContext\n extends Weaken<AcmsContextWithSearchParams, 'bid' | 'cid' | 'eid' | 'uid' | 'tag' | 'date'> {\n bid?: AcmsContextWithSearchParams['bid'] | string;\n cid?: AcmsContextWithSearchParams['cid'] | string;\n eid?: AcmsContextWithSearchParams['eid'] | string;\n uid?: AcmsContextWithSearchParams['uid'] | string;\n tag?: AcmsContextWithSearchParams['tag'] | string;\n date?: AcmsContextWithSearchParams['date'] | string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n Query?: Record<string, any>; // 互換性のため\n}\n\ninterface AcmsLinkOptions {\n /**\n * 現在のURLコンテキストを継承するかどうか\n * デフォルト: false\n */\n inherit: boolean;\n\n /**\n * tplコンテキストがajaxから始まる場合キャッシュバスティングようのクエリを自動で付与するかどうか\n * デフォルト: true\n */\n ajaxCacheBusting: boolean;\n}\n\nconst defaultOptions = {\n inherit: false,\n ajaxCacheBusting: true,\n} as const satisfies AcmsLinkOptions;\n\n/**\n * AcmsLinkContext と AcmsContext の互換性を保つための変換\n */\nfunction toAcmsContext(context: AcmsLinkContext, options: AcmsLinkOptions): AcmsContextWithSearchParams {\n const bid = typeof context.bid === 'string' ? parseInt(context.bid, 10) : context.bid;\n const cid = typeof context.cid === 'string' ? parseInt(context.cid, 10) : context.cid;\n const eid = typeof context.eid === 'string' ? parseInt(context.eid, 10) : context.eid;\n const uid = typeof context.uid === 'string' ? parseInt(context.uid, 10) : context.uid;\n const tag = typeof context.tag === 'string' ? context.tag.split('/') : context.tag;\n let { date } = context;\n if (typeof date === 'string') {\n const [year, month, day] = date.split('/').map((v) => parseInt(v, 10));\n if (year !== undefined && !isNaN(year)) {\n date = { year };\n if (month !== undefined && !isNaN(month)) {\n date.month = month;\n if (day !== undefined && !isNaN(day)) {\n date.day = day;\n }\n }\n } else {\n date = undefined;\n }\n }\n // 互換性を考慮して、Query でも searchParams を指定できるようにする\n const _searchParams = context.searchParams || context.Query;\n const { Query: _, ...inheritContext } = context; // eslint-disable-line @typescript-eslint/no-unused-vars\n let searchParams = _searchParams instanceof URLSearchParams ? parseUrlSearchParams(_searchParams) : _searchParams;\n if (options.ajaxCacheBusting && context.tpl && /^ajax\\//.test(context.tpl)) {\n searchParams = {\n ...searchParams,\n v: Date.now().toString(),\n };\n }\n return {\n ...inheritContext,\n bid,\n cid,\n eid,\n uid,\n tag,\n date,\n searchParams,\n };\n}\n\n/** acmsLink が必要とする Config の最小サブセット(ACMS.Config 全体に依存しない) */\nexport interface AcmsLinkConfig {\n scriptRoot: string;\n bid?: string;\n cid?: string;\n eid?: string;\n admin?: string;\n keyword?: string;\n}\n\nexport interface AcmsLinkDeps {\n /** コール時評価を維持するためアクセサで受ける(生成時キャプチャすると Config の実行時書き換えに追従できない) */\n getConfig: () => AcmsLinkConfig;\n /** createAcmsPathHelper(segments) が返す acmsPath */\n acmsPath: (context: AcmsContextWithSearchParams) => string;\n}\n\nexport type AcmsLink = (context: AcmsLinkContext, options?: boolean | Partial<AcmsLinkOptions>) => string;\n\n/**\n * acmsLink\n */\nexport function createAcmsLink({ getConfig, acmsPath }: AcmsLinkDeps): AcmsLink {\n return function acmsLink(context, options = {}) {\n const _options: Partial<AcmsLinkOptions> = typeof options === 'boolean' ? { inherit: options } : options;\n const config: AcmsLinkOptions = { ...defaultOptions, ..._options };\n const Config = getConfig();\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n function empty(value: any) {\n return typeof value === 'undefined' || value === null;\n }\n\n //-----------------\n // inherit context\n if (config.inherit) {\n if (empty(context.cid)) {\n context.cid = Config.cid;\n }\n if (empty(context.eid)) {\n context.eid = Config.eid;\n }\n if (empty(context.admin)) {\n context.admin = Config.admin;\n }\n if (empty(context.keyword)) {\n context.keyword = Config.keyword;\n }\n }\n\n if (empty(context.bid) || context.bid === '') {\n context.bid = Config.bid;\n }\n\n let url = Config.scriptRoot;\n url += acmsPath(toAcmsContext(context, config));\n\n return url;\n };\n}\n"],"mappings":";AACA,SAAS,4BAA4B;AA6BrC,IAAM,iBAAiB;AAAA,EACrB,SAAS;AAAA,EACT,kBAAkB;AACpB;AAKA,SAAS,cAAc,SAA0B,SAAuD;AACtG,QAAM,MAAM,OAAO,QAAQ,QAAQ,WAAW,SAAS,QAAQ,KAAK,EAAE,IAAI,QAAQ;AAClF,QAAM,MAAM,OAAO,QAAQ,QAAQ,WAAW,SAAS,QAAQ,KAAK,EAAE,IAAI,QAAQ;AAClF,QAAM,MAAM,OAAO,QAAQ,QAAQ,WAAW,SAAS,QAAQ,KAAK,EAAE,IAAI,QAAQ;AAClF,QAAM,MAAM,OAAO,QAAQ,QAAQ,WAAW,SAAS,QAAQ,KAAK,EAAE,IAAI,QAAQ;AAClF,QAAM,MAAM,OAAO,QAAQ,QAAQ,WAAW,QAAQ,IAAI,MAAM,GAAG,IAAI,QAAQ;AAC/E,MAAI,EAAE,KAAK,IAAI;AACf,MAAI,OAAO,SAAS,UAAU;AAC5B,UAAM,CAAC,MAAM,OAAO,GAAG,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC;AACrE,QAAI,SAAS,UAAa,CAAC,MAAM,IAAI,GAAG;AACtC,aAAO,EAAE,KAAK;AACd,UAAI,UAAU,UAAa,CAAC,MAAM,KAAK,GAAG;AACxC,aAAK,QAAQ;AACb,YAAI,QAAQ,UAAa,CAAC,MAAM,GAAG,GAAG;AACpC,eAAK,MAAM;AAAA,QACb;AAAA,MACF;AAAA,IACF,OAAO;AACL,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,gBAAgB,QAAQ,gBAAgB,QAAQ;AACtD,QAAM,EAAE,OAAO,GAAG,GAAG,eAAe,IAAI;AACxC,MAAI,eAAe,yBAAyB,kBAAkB,qBAAqB,aAAa,IAAI;AACpG,MAAI,QAAQ,oBAAoB,QAAQ,OAAO,UAAU,KAAK,QAAQ,GAAG,GAAG;AAC1E,mBAAe;AAAA,MACb,GAAG;AAAA,MACH,GAAG,KAAK,IAAI,EAAE,SAAS;AAAA,IACzB;AAAA,EACF;AACA,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAwBO,SAAS,eAAe,EAAE,WAAW,SAAS,GAA2B;AAC9E,SAAO,SAAS,SAAS,SAAS,UAAU,CAAC,GAAG;AAC9C,UAAM,WAAqC,OAAO,YAAY,YAAY,EAAE,SAAS,QAAQ,IAAI;AACjG,UAAM,SAA0B,EAAE,GAAG,gBAAgB,GAAG,SAAS;AACjE,UAAM,SAAS,UAAU;AAEzB,aAAS,MAAM,OAAY;AACzB,aAAO,OAAO,UAAU,eAAe,UAAU;AAAA,IACnD;AAIA,QAAI,OAAO,SAAS;AAClB,UAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,gBAAQ,MAAM,OAAO;AAAA,MACvB;AACA,UAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,gBAAQ,MAAM,OAAO;AAAA,MACvB;AACA,UAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,gBAAQ,QAAQ,OAAO;AAAA,MACzB;AACA,UAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,gBAAQ,UAAU,OAAO;AAAA,MAC3B;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,GAAG,KAAK,QAAQ,QAAQ,IAAI;AAC5C,cAAQ,MAAM,OAAO;AAAA,IACvB;AAEA,QAAI,MAAM,OAAO;AACjB,WAAO,SAAS,cAAc,SAAS,MAAM,CAAC;AAE9C,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AcmsFieldList
|
|
3
|
+
} from "./chunk-OUKSKSZA.mjs";
|
|
4
|
+
import {
|
|
5
|
+
formatDate,
|
|
6
|
+
mergeConfig,
|
|
7
|
+
splitPath
|
|
8
|
+
} from "./chunk-XTN64CHF.mjs";
|
|
9
|
+
import {
|
|
10
|
+
defaultAcmsPathSegments
|
|
11
|
+
} from "./chunk-OJI2ZTVL.mjs";
|
|
12
|
+
|
|
13
|
+
// src/parseAcmsPath.ts
|
|
14
|
+
import isDateString from "@ablogcms/utils/is-date-string";
|
|
15
|
+
var integerSegmentKeys = [
|
|
16
|
+
"bid",
|
|
17
|
+
"uid",
|
|
18
|
+
"cid",
|
|
19
|
+
"eid",
|
|
20
|
+
"page",
|
|
21
|
+
"limit"
|
|
22
|
+
];
|
|
23
|
+
function isNumericSlug(slug) {
|
|
24
|
+
return slug !== void 0 && /^\d+$/.test(slug);
|
|
25
|
+
}
|
|
26
|
+
function collectSlugs(slugs, startIndex, segmentSlugs, integerSegmentSlugs) {
|
|
27
|
+
const collected = [];
|
|
28
|
+
for (let i = startIndex; i < slugs.length; i++) {
|
|
29
|
+
const slug = slugs[i];
|
|
30
|
+
if (integerSegmentSlugs.includes(slug)) {
|
|
31
|
+
if (isNumericSlug(slugs[i + 1])) break;
|
|
32
|
+
} else if (segmentSlugs.includes(slug)) {
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
collected.push(slug);
|
|
36
|
+
}
|
|
37
|
+
return collected.join("/");
|
|
38
|
+
}
|
|
39
|
+
function extractSpanSlugs(start, end) {
|
|
40
|
+
const formattedStart = isDateString(start) ? formatDate(new Date(start)) : void 0;
|
|
41
|
+
const formattedEnd = isDateString(end) ? formatDate(new Date(end)) : void 0;
|
|
42
|
+
return [formattedStart, formattedEnd];
|
|
43
|
+
}
|
|
44
|
+
function isYearSlug(slug) {
|
|
45
|
+
const year = parseInt(slug, 10);
|
|
46
|
+
return year >= 1e3 && year <= 9999;
|
|
47
|
+
}
|
|
48
|
+
function isMonthSlug(slug) {
|
|
49
|
+
const month = parseInt(slug, 10);
|
|
50
|
+
return month >= 1 && month <= 12;
|
|
51
|
+
}
|
|
52
|
+
function isDaySlug(slug) {
|
|
53
|
+
const day = parseInt(slug, 10);
|
|
54
|
+
return day >= 1 && day <= 31;
|
|
55
|
+
}
|
|
56
|
+
function getDefaultSpan(context) {
|
|
57
|
+
let start = new Date(1e3, 0, 1, 0, 0, 0);
|
|
58
|
+
let end = new Date(9999, 11, 31, 23, 59, 59);
|
|
59
|
+
if (context.date !== void 0) {
|
|
60
|
+
start = new Date(context.date.year, (context.date.month ?? 1) - 1, context.date.day ?? 1);
|
|
61
|
+
end = new Date(context.date.year, (context.date.month ?? 12) - 1, context.date.day ?? 31, 23, 59, 59);
|
|
62
|
+
}
|
|
63
|
+
return { start: formatDate(start), end: formatDate(end) };
|
|
64
|
+
}
|
|
65
|
+
var defaultOptions = {
|
|
66
|
+
segments: defaultAcmsPathSegments
|
|
67
|
+
};
|
|
68
|
+
function parseAcmsPath(path, options = {}) {
|
|
69
|
+
const { segments } = mergeConfig(defaultOptions, options);
|
|
70
|
+
const slugs = splitPath(path).filter((slug) => slug);
|
|
71
|
+
const context = {};
|
|
72
|
+
const unresolvedSlugs = [];
|
|
73
|
+
const segmentKeys = Object.keys(segments);
|
|
74
|
+
const segmentSlugs = Object.values(segments);
|
|
75
|
+
const integerSegmentSlugs = integerSegmentKeys.map((key) => segments[key]).filter((slug) => slug !== void 0);
|
|
76
|
+
for (let i = 0; i < slugs.length; i++) {
|
|
77
|
+
const slug = slugs[i];
|
|
78
|
+
if (segmentSlugs.includes(slug)) {
|
|
79
|
+
const segmentKey = segmentKeys.find((k) => segments[k] === slug);
|
|
80
|
+
if (segmentKey !== void 0) {
|
|
81
|
+
const value = slugs[i + 1];
|
|
82
|
+
if (value !== void 0) {
|
|
83
|
+
switch (segmentKey) {
|
|
84
|
+
case "bid":
|
|
85
|
+
case "uid":
|
|
86
|
+
case "cid":
|
|
87
|
+
case "eid":
|
|
88
|
+
case "page":
|
|
89
|
+
case "limit":
|
|
90
|
+
if (isNumericSlug(value)) {
|
|
91
|
+
context[segmentKey] = parseInt(value, 10);
|
|
92
|
+
i++;
|
|
93
|
+
} else {
|
|
94
|
+
unresolvedSlugs.push(slug);
|
|
95
|
+
}
|
|
96
|
+
break;
|
|
97
|
+
case "utid":
|
|
98
|
+
case "admin":
|
|
99
|
+
case "keyword":
|
|
100
|
+
case "order":
|
|
101
|
+
context[segmentKey] = value;
|
|
102
|
+
i++;
|
|
103
|
+
break;
|
|
104
|
+
case "api": {
|
|
105
|
+
if (/^v\d+$/.test(value)) {
|
|
106
|
+
context.apiVersion = value;
|
|
107
|
+
const moduleId = slugs[i + 2];
|
|
108
|
+
if (moduleId !== void 0) {
|
|
109
|
+
context.api = moduleId;
|
|
110
|
+
i += 2;
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
context.apiVersion = "v1";
|
|
114
|
+
context.api = value;
|
|
115
|
+
i++;
|
|
116
|
+
}
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
case "tpl":
|
|
120
|
+
context.tpl = collectSlugs(slugs, i + 1, segmentSlugs, integerSegmentSlugs);
|
|
121
|
+
i += context.tpl.split("/").length;
|
|
122
|
+
break;
|
|
123
|
+
case "field": {
|
|
124
|
+
const string = collectSlugs(slugs, i + 1, segmentSlugs, integerSegmentSlugs);
|
|
125
|
+
context.field = AcmsFieldList.fromString(string);
|
|
126
|
+
i += string.split("/").length;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
case "tag":
|
|
130
|
+
context.tag = collectSlugs(slugs, i + 1, segmentSlugs, integerSegmentSlugs).split("/").map((tag) => tag.trim());
|
|
131
|
+
i += context.tag.length;
|
|
132
|
+
break;
|
|
133
|
+
case "span": {
|
|
134
|
+
const [start, end] = extractSpanSlugs(slugs[i - 1], value);
|
|
135
|
+
if (start !== void 0 && end !== void 0) {
|
|
136
|
+
context.span = { start, end };
|
|
137
|
+
unresolvedSlugs.pop();
|
|
138
|
+
i++;
|
|
139
|
+
}
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
default:
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
unresolvedSlugs.push(slug);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
for (let i = 0; i < unresolvedSlugs.length; i++) {
|
|
152
|
+
const slug = unresolvedSlugs[i];
|
|
153
|
+
if (isYearSlug(slug)) {
|
|
154
|
+
const year = slug;
|
|
155
|
+
const month = unresolvedSlugs[i + 1];
|
|
156
|
+
if (month !== void 0 && isMonthSlug(month)) {
|
|
157
|
+
const day = unresolvedSlugs[i + 2];
|
|
158
|
+
if (day !== void 0 && isDaySlug(day)) {
|
|
159
|
+
context.date = {
|
|
160
|
+
year: parseInt(year, 10),
|
|
161
|
+
month: parseInt(month, 10),
|
|
162
|
+
day: parseInt(day, 10)
|
|
163
|
+
};
|
|
164
|
+
unresolvedSlugs.splice(i, 3);
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
context.date = {
|
|
168
|
+
year: parseInt(year, 10),
|
|
169
|
+
month: parseInt(month, 10)
|
|
170
|
+
};
|
|
171
|
+
unresolvedSlugs.splice(i, 2);
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
context.date = { year: parseInt(year, 10) };
|
|
175
|
+
unresolvedSlugs.splice(i, 1);
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (context.page === void 0) {
|
|
180
|
+
context.page = 1;
|
|
181
|
+
}
|
|
182
|
+
if (context.span === void 0) {
|
|
183
|
+
context.span = getDefaultSpan(context);
|
|
184
|
+
}
|
|
185
|
+
context.unresolvedPath = unresolvedSlugs.join("/");
|
|
186
|
+
return context;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export {
|
|
190
|
+
parseAcmsPath
|
|
191
|
+
};
|
|
192
|
+
//# sourceMappingURL=chunk-GHGJBKQU.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/parseAcmsPath.ts"],"sourcesContent":["import isDateString from '@ablogcms/utils/is-date-string';\nimport { defaultAcmsPathSegments } from './defaults';\nimport type { AcmsContext, AcmsPathSegments, ParseAcmsPathConfig, ParseAcmsPathOptions } from './types';\nimport { formatDate, mergeConfig, splitPath } from './utils';\nimport AcmsFieldList from './acmsField';\n\nconst integerSegmentKeys = [\n 'bid',\n 'uid',\n 'cid',\n 'eid',\n 'page',\n 'limit',\n] as const satisfies readonly (keyof AcmsPathSegments)[];\n\nfunction isNumericSlug(slug: string | undefined): slug is string {\n return slug !== undefined && /^\\d+$/.test(slug);\n}\n\nfunction collectSlugs(\n slugs: string[],\n startIndex: number,\n segmentSlugs: string[],\n integerSegmentSlugs: string[]\n): string {\n const collected = [];\n for (let i = startIndex; i < slugs.length; i++) {\n const slug = slugs[i];\n if (integerSegmentSlugs.includes(slug)) {\n if (isNumericSlug(slugs[i + 1])) break;\n } else if (segmentSlugs.includes(slug)) {\n break;\n }\n collected.push(slug);\n }\n return collected.join('/');\n}\n\nfunction extractSpanSlugs(start: string, end: string): [string | undefined, string | undefined] {\n const formattedStart = isDateString(start) ? formatDate(new Date(start)) : undefined;\n const formattedEnd = isDateString(end) ? formatDate(new Date(end)) : undefined;\n return [formattedStart, formattedEnd];\n}\n\nfunction isYearSlug(slug: string): boolean {\n const year = parseInt(slug, 10);\n return year >= 1000 && year <= 9999;\n}\n\nfunction isMonthSlug(slug: string): boolean {\n const month = parseInt(slug, 10);\n return month >= 1 && month <= 12;\n}\n\nfunction isDaySlug(slug: string): boolean {\n const day = parseInt(slug, 10);\n return day >= 1 && day <= 31;\n}\n\nfunction getDefaultSpan(context: AcmsContext): Required<AcmsContext>['span'] {\n let start = new Date(1000, 0, 1, 0, 0, 0);\n let end = new Date(9999, 11, 31, 23, 59, 59);\n if (context.date !== undefined) {\n start = new Date(context.date.year, (context.date.month ?? 1) - 1, context.date.day ?? 1);\n end = new Date(context.date.year, (context.date.month ?? 12) - 1, context.date.day ?? 31, 23, 59, 59);\n }\n return { start: formatDate(start), end: formatDate(end) };\n}\n\nconst defaultOptions = {\n segments: defaultAcmsPathSegments,\n} as const satisfies ParseAcmsPathConfig;\n\nexport default function parseAcmsPath(path: string, options: ParseAcmsPathOptions = {}): AcmsContext {\n const { segments } = mergeConfig(defaultOptions, options) as ParseAcmsPathConfig;\n\n const slugs = splitPath(path).filter((slug) => slug);\n const context: AcmsContext = {};\n const unresolvedSlugs = [];\n const segmentKeys = Object.keys(segments);\n const segmentSlugs = Object.values(segments) as string[];\n const integerSegmentSlugs = integerSegmentKeys\n .map((key) => segments[key])\n .filter((slug): slug is string => slug !== undefined);\n\n for (let i = 0; i < slugs.length; i++) {\n const slug = slugs[i];\n\n if (segmentSlugs.includes(slug)) {\n const segmentKey = segmentKeys.find((k) => segments[k as keyof AcmsPathSegments] === slug);\n if (segmentKey !== undefined) {\n const value = slugs[i + 1];\n if (value !== undefined) {\n switch (segmentKey) {\n case 'bid':\n case 'uid':\n case 'cid':\n case 'eid':\n case 'page':\n case 'limit':\n if (isNumericSlug(value)) {\n context[segmentKey] = parseInt(value, 10);\n i++;\n } else {\n unresolvedSlugs.push(slug);\n }\n break;\n case 'utid':\n case 'admin':\n case 'keyword':\n case 'order':\n context[segmentKey] = value;\n i++;\n break;\n case 'api': {\n // Check if next slug is a version (e.g., 'v2', 'v3')\n if (/^v\\d+$/.test(value)) {\n context.apiVersion = value as 'v1' | 'v2';\n const moduleId = slugs[i + 2];\n if (moduleId !== undefined) {\n context.api = moduleId;\n i += 2;\n }\n } else {\n // No version means v1\n context.apiVersion = 'v1';\n context.api = value;\n i++;\n }\n break;\n }\n case 'tpl':\n context.tpl = collectSlugs(slugs, i + 1, segmentSlugs, integerSegmentSlugs);\n i += context.tpl.split('/').length; // 次のセグメントまでスキップ\n break;\n case 'field': {\n const string = collectSlugs(slugs, i + 1, segmentSlugs, integerSegmentSlugs);\n context.field = AcmsFieldList.fromString(string);\n i += string.split('/').length; // 次のセグメントまでスキップ\n break;\n }\n case 'tag':\n context.tag = collectSlugs(slugs, i + 1, segmentSlugs, integerSegmentSlugs)\n .split('/')\n .map((tag) => tag.trim());\n i += context.tag.length; // 次のセグメントまでスキップ\n break;\n case 'span': {\n const [start, end] = extractSpanSlugs(slugs[i - 1], value);\n if (start !== undefined && end !== undefined) {\n context.span = { start, end };\n unresolvedSlugs.pop(); // spanのスラッグを削除\n i++;\n }\n break;\n }\n default:\n break;\n }\n }\n }\n } else {\n unresolvedSlugs.push(slug);\n }\n }\n\n for (let i = 0; i < unresolvedSlugs.length; i++) {\n const slug = unresolvedSlugs[i];\n if (isYearSlug(slug)) {\n const year = slug;\n const month = unresolvedSlugs[i + 1];\n if (month !== undefined && isMonthSlug(month)) {\n const day = unresolvedSlugs[i + 2];\n if (day !== undefined && isDaySlug(day)) {\n context.date = {\n year: parseInt(year, 10),\n month: parseInt(month, 10),\n day: parseInt(day, 10),\n };\n unresolvedSlugs.splice(i, 3);\n continue;\n }\n context.date = {\n year: parseInt(year, 10),\n month: parseInt(month, 10),\n };\n unresolvedSlugs.splice(i, 2);\n continue;\n }\n context.date = { year: parseInt(year, 10) };\n unresolvedSlugs.splice(i, 1);\n continue;\n }\n }\n\n if (context.page === undefined) {\n context.page = 1;\n }\n if (context.span === undefined) {\n context.span = getDefaultSpan(context);\n }\n\n context.unresolvedPath = unresolvedSlugs.join('/');\n\n return context;\n}\n"],"mappings":"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","names":[]}
|