@terminalfour/terminalfour-js 1.0.0-rc.1
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/LICENSE.md +106 -0
- package/README.md +169 -0
- package/dist/cjs/element-resolver.d.ts +115 -0
- package/dist/cjs/element-resolver.d.ts.map +1 -0
- package/dist/cjs/element-resolver.js +391 -0
- package/dist/cjs/element-resolver.js.map +1 -0
- package/dist/cjs/errors.d.ts +21 -0
- package/dist/cjs/errors.d.ts.map +1 -0
- package/dist/cjs/errors.js +21 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/handlebars.d.ts +123 -0
- package/dist/cjs/handlebars.d.ts.map +1 -0
- package/dist/cjs/handlebars.js +306 -0
- package/dist/cjs/handlebars.js.map +1 -0
- package/dist/cjs/http-client.d.ts +21 -0
- package/dist/cjs/http-client.d.ts.map +1 -0
- package/dist/cjs/http-client.js +126 -0
- package/dist/cjs/http-client.js.map +1 -0
- package/dist/cjs/index.d.ts +37 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +55 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/media-category-ref.d.ts +78 -0
- package/dist/cjs/media-category-ref.d.ts.map +1 -0
- package/dist/cjs/media-category-ref.js +184 -0
- package/dist/cjs/media-category-ref.js.map +1 -0
- package/dist/cjs/media-library.d.ts +30 -0
- package/dist/cjs/media-library.d.ts.map +1 -0
- package/dist/cjs/media-library.js +77 -0
- package/dist/cjs/media-library.js.map +1 -0
- package/dist/cjs/models/content-item.d.ts +80 -0
- package/dist/cjs/models/content-item.d.ts.map +1 -0
- package/dist/cjs/models/content-item.js +682 -0
- package/dist/cjs/models/content-item.js.map +1 -0
- package/dist/cjs/models/media-category-item.d.ts +29 -0
- package/dist/cjs/models/media-category-item.d.ts.map +1 -0
- package/dist/cjs/models/media-category-item.js +33 -0
- package/dist/cjs/models/media-category-item.js.map +1 -0
- package/dist/cjs/models/media-item.d.ts +74 -0
- package/dist/cjs/models/media-item.d.ts.map +1 -0
- package/dist/cjs/models/media-item.js +188 -0
- package/dist/cjs/models/media-item.js.map +1 -0
- package/dist/cjs/models/section-item.d.ts +58 -0
- package/dist/cjs/models/section-item.d.ts.map +1 -0
- package/dist/cjs/models/section-item.js +166 -0
- package/dist/cjs/models/section-item.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/resources/channel-resource.d.ts +112 -0
- package/dist/cjs/resources/channel-resource.d.ts.map +1 -0
- package/dist/cjs/resources/channel-resource.js +107 -0
- package/dist/cjs/resources/channel-resource.js.map +1 -0
- package/dist/cjs/resources/content-resource.d.ts +50 -0
- package/dist/cjs/resources/content-resource.d.ts.map +1 -0
- package/dist/cjs/resources/content-resource.js +286 -0
- package/dist/cjs/resources/content-resource.js.map +1 -0
- package/dist/cjs/resources/content-type-resource.d.ts +283 -0
- package/dist/cjs/resources/content-type-resource.d.ts.map +1 -0
- package/dist/cjs/resources/content-type-resource.js +970 -0
- package/dist/cjs/resources/content-type-resource.js.map +1 -0
- package/dist/cjs/resources/group-resource.d.ts +96 -0
- package/dist/cjs/resources/group-resource.d.ts.map +1 -0
- package/dist/cjs/resources/group-resource.js +213 -0
- package/dist/cjs/resources/group-resource.js.map +1 -0
- package/dist/cjs/resources/list-resource.d.ts +111 -0
- package/dist/cjs/resources/list-resource.d.ts.map +1 -0
- package/dist/cjs/resources/list-resource.js +179 -0
- package/dist/cjs/resources/list-resource.js.map +1 -0
- package/dist/cjs/resources/media-resource.d.ts +69 -0
- package/dist/cjs/resources/media-resource.d.ts.map +1 -0
- package/dist/cjs/resources/media-resource.js +210 -0
- package/dist/cjs/resources/media-resource.js.map +1 -0
- package/dist/cjs/resources/media-type-resource.d.ts +70 -0
- package/dist/cjs/resources/media-type-resource.d.ts.map +1 -0
- package/dist/cjs/resources/media-type-resource.js +195 -0
- package/dist/cjs/resources/media-type-resource.js.map +1 -0
- package/dist/cjs/resources/navigation-resource.d.ts +664 -0
- package/dist/cjs/resources/navigation-resource.d.ts.map +1 -0
- package/dist/cjs/resources/navigation-resource.js +2349 -0
- package/dist/cjs/resources/navigation-resource.js.map +1 -0
- package/dist/cjs/resources/page-layout-resource.d.ts +83 -0
- package/dist/cjs/resources/page-layout-resource.d.ts.map +1 -0
- package/dist/cjs/resources/page-layout-resource.js +214 -0
- package/dist/cjs/resources/page-layout-resource.js.map +1 -0
- package/dist/cjs/resources/user-resource.d.ts +126 -0
- package/dist/cjs/resources/user-resource.d.ts.map +1 -0
- package/dist/cjs/resources/user-resource.js +317 -0
- package/dist/cjs/resources/user-resource.js.map +1 -0
- package/dist/cjs/section-ref.d.ts +185 -0
- package/dist/cjs/section-ref.d.ts.map +1 -0
- package/dist/cjs/section-ref.js +813 -0
- package/dist/cjs/section-ref.js.map +1 -0
- package/dist/cjs/site-structure.d.ts +18 -0
- package/dist/cjs/site-structure.d.ts.map +1 -0
- package/dist/cjs/site-structure.js +57 -0
- package/dist/cjs/site-structure.js.map +1 -0
- package/dist/cjs/t4-client.d.ts +121 -0
- package/dist/cjs/t4-client.d.ts.map +1 -0
- package/dist/cjs/t4-client.js +190 -0
- package/dist/cjs/t4-client.js.map +1 -0
- package/dist/cjs/type-registry.d.ts +31 -0
- package/dist/cjs/type-registry.d.ts.map +1 -0
- package/dist/cjs/type-registry.js +76 -0
- package/dist/cjs/type-registry.js.map +1 -0
- package/dist/cjs/types.d.ts +211 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +3 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/utils.d.ts +147 -0
- package/dist/cjs/utils.d.ts.map +1 -0
- package/dist/cjs/utils.js +408 -0
- package/dist/cjs/utils.js.map +1 -0
- package/dist/esm/element-resolver.d.ts +115 -0
- package/dist/esm/element-resolver.d.ts.map +1 -0
- package/dist/esm/element-resolver.js +387 -0
- package/dist/esm/element-resolver.js.map +1 -0
- package/dist/esm/errors.d.ts +21 -0
- package/dist/esm/errors.d.ts.map +1 -0
- package/dist/esm/errors.js +17 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/handlebars.d.ts +123 -0
- package/dist/esm/handlebars.d.ts.map +1 -0
- package/dist/esm/handlebars.js +300 -0
- package/dist/esm/handlebars.js.map +1 -0
- package/dist/esm/http-client.d.ts +21 -0
- package/dist/esm/http-client.d.ts.map +1 -0
- package/dist/esm/http-client.js +122 -0
- package/dist/esm/http-client.js.map +1 -0
- package/dist/esm/index.d.ts +37 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +26 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/media-category-ref.d.ts +78 -0
- package/dist/esm/media-category-ref.d.ts.map +1 -0
- package/dist/esm/media-category-ref.js +180 -0
- package/dist/esm/media-category-ref.js.map +1 -0
- package/dist/esm/media-library.d.ts +30 -0
- package/dist/esm/media-library.d.ts.map +1 -0
- package/dist/esm/media-library.js +73 -0
- package/dist/esm/media-library.js.map +1 -0
- package/dist/esm/models/content-item.d.ts +80 -0
- package/dist/esm/models/content-item.d.ts.map +1 -0
- package/dist/esm/models/content-item.js +676 -0
- package/dist/esm/models/content-item.js.map +1 -0
- package/dist/esm/models/media-category-item.d.ts +29 -0
- package/dist/esm/models/media-category-item.d.ts.map +1 -0
- package/dist/esm/models/media-category-item.js +29 -0
- package/dist/esm/models/media-category-item.js.map +1 -0
- package/dist/esm/models/media-item.d.ts +74 -0
- package/dist/esm/models/media-item.d.ts.map +1 -0
- package/dist/esm/models/media-item.js +184 -0
- package/dist/esm/models/media-item.js.map +1 -0
- package/dist/esm/models/section-item.d.ts +58 -0
- package/dist/esm/models/section-item.d.ts.map +1 -0
- package/dist/esm/models/section-item.js +162 -0
- package/dist/esm/models/section-item.js.map +1 -0
- package/dist/esm/resources/channel-resource.d.ts +112 -0
- package/dist/esm/resources/channel-resource.d.ts.map +1 -0
- package/dist/esm/resources/channel-resource.js +102 -0
- package/dist/esm/resources/channel-resource.js.map +1 -0
- package/dist/esm/resources/content-resource.d.ts +50 -0
- package/dist/esm/resources/content-resource.d.ts.map +1 -0
- package/dist/esm/resources/content-resource.js +282 -0
- package/dist/esm/resources/content-resource.js.map +1 -0
- package/dist/esm/resources/content-type-resource.d.ts +283 -0
- package/dist/esm/resources/content-type-resource.d.ts.map +1 -0
- package/dist/esm/resources/content-type-resource.js +964 -0
- package/dist/esm/resources/content-type-resource.js.map +1 -0
- package/dist/esm/resources/group-resource.d.ts +96 -0
- package/dist/esm/resources/group-resource.d.ts.map +1 -0
- package/dist/esm/resources/group-resource.js +208 -0
- package/dist/esm/resources/group-resource.js.map +1 -0
- package/dist/esm/resources/list-resource.d.ts +111 -0
- package/dist/esm/resources/list-resource.d.ts.map +1 -0
- package/dist/esm/resources/list-resource.js +174 -0
- package/dist/esm/resources/list-resource.js.map +1 -0
- package/dist/esm/resources/media-resource.d.ts +69 -0
- package/dist/esm/resources/media-resource.d.ts.map +1 -0
- package/dist/esm/resources/media-resource.js +206 -0
- package/dist/esm/resources/media-resource.js.map +1 -0
- package/dist/esm/resources/media-type-resource.d.ts +70 -0
- package/dist/esm/resources/media-type-resource.d.ts.map +1 -0
- package/dist/esm/resources/media-type-resource.js +190 -0
- package/dist/esm/resources/media-type-resource.js.map +1 -0
- package/dist/esm/resources/navigation-resource.d.ts +664 -0
- package/dist/esm/resources/navigation-resource.d.ts.map +1 -0
- package/dist/esm/resources/navigation-resource.js +2344 -0
- package/dist/esm/resources/navigation-resource.js.map +1 -0
- package/dist/esm/resources/page-layout-resource.d.ts +83 -0
- package/dist/esm/resources/page-layout-resource.d.ts.map +1 -0
- package/dist/esm/resources/page-layout-resource.js +209 -0
- package/dist/esm/resources/page-layout-resource.js.map +1 -0
- package/dist/esm/resources/user-resource.d.ts +126 -0
- package/dist/esm/resources/user-resource.d.ts.map +1 -0
- package/dist/esm/resources/user-resource.js +312 -0
- package/dist/esm/resources/user-resource.js.map +1 -0
- package/dist/esm/section-ref.d.ts +185 -0
- package/dist/esm/section-ref.d.ts.map +1 -0
- package/dist/esm/section-ref.js +808 -0
- package/dist/esm/section-ref.js.map +1 -0
- package/dist/esm/site-structure.d.ts +18 -0
- package/dist/esm/site-structure.d.ts.map +1 -0
- package/dist/esm/site-structure.js +53 -0
- package/dist/esm/site-structure.js.map +1 -0
- package/dist/esm/t4-client.d.ts +121 -0
- package/dist/esm/t4-client.d.ts.map +1 -0
- package/dist/esm/t4-client.js +186 -0
- package/dist/esm/t4-client.js.map +1 -0
- package/dist/esm/type-registry.d.ts +31 -0
- package/dist/esm/type-registry.d.ts.map +1 -0
- package/dist/esm/type-registry.js +72 -0
- package/dist/esm/type-registry.js.map +1 -0
- package/dist/esm/types.d.ts +211 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/utils.d.ts +147 -0
- package/dist/esm/utils.d.ts.map +1 -0
- package/dist/esm/utils.js +355 -0
- package/dist/esm/utils.js.map +1 -0
- package/docs/channels.md +62 -0
- package/docs/content-types.md +313 -0
- package/docs/content.md +199 -0
- package/docs/error-handling.md +86 -0
- package/docs/getting-started.md +146 -0
- package/docs/groups-and-users.md +167 -0
- package/docs/handlebars.md +145 -0
- package/docs/lists.md +98 -0
- package/docs/media-types.md +111 -0
- package/docs/media.md +169 -0
- package/docs/navigation/a-to-z.md +62 -0
- package/docs/navigation/breadcrumbs.md +67 -0
- package/docs/navigation/css-selector.md +53 -0
- package/docs/navigation/generate-file.md +48 -0
- package/docs/navigation/keyword-search.md +134 -0
- package/docs/navigation/language-switcher.md +37 -0
- package/docs/navigation/link-menu.md +105 -0
- package/docs/navigation/pagination.md +80 -0
- package/docs/navigation/previous-next-fulltext.md +43 -0
- package/docs/navigation/publish-to-one-file.md +93 -0
- package/docs/navigation/related-content.md +79 -0
- package/docs/navigation/related-section-branch.md +31 -0
- package/docs/navigation/return-to-index.md +35 -0
- package/docs/navigation/section-details.md +51 -0
- package/docs/navigation/section-iterator.md +33 -0
- package/docs/navigation/section-meta-info.md +39 -0
- package/docs/navigation/site-map.md +58 -0
- package/docs/navigation/top-content.md +80 -0
- package/docs/navigation/top-stories.md +47 -0
- package/docs/navigation.md +134 -0
- package/docs/page-layouts.md +71 -0
- package/docs/sections.md +224 -0
- package/docs/typescript.md +124 -0
- package/package.json +64 -0
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves the effective language for an API request.
|
|
3
|
+
*
|
|
4
|
+
* Resolution order:
|
|
5
|
+
* 1. Explicit per-call override
|
|
6
|
+
* 2. Client-level default language
|
|
7
|
+
* 3. Hardcoded fallback "en"
|
|
8
|
+
*/
|
|
9
|
+
export function resolveLanguage(override, defaultLang) {
|
|
10
|
+
return override ?? defaultLang ?? 'en';
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Converts a DateInput (Date, timestamp in ms, or date string) to a
|
|
14
|
+
* millisecond timestamp suitable for the T4 API.
|
|
15
|
+
* Returns null if the input is null or undefined.
|
|
16
|
+
*/
|
|
17
|
+
export function toTimestamp(value) {
|
|
18
|
+
if (value == null)
|
|
19
|
+
return null;
|
|
20
|
+
if (value instanceof Date)
|
|
21
|
+
return value.getTime();
|
|
22
|
+
if (typeof value === 'number')
|
|
23
|
+
return value;
|
|
24
|
+
if (typeof value === 'string') {
|
|
25
|
+
const ts = new Date(value).getTime();
|
|
26
|
+
return isNaN(ts) ? null : ts;
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
const HTML_ENTITIES = {
|
|
31
|
+
'&': '&',
|
|
32
|
+
'<': '<',
|
|
33
|
+
'>': '>',
|
|
34
|
+
'"': '"',
|
|
35
|
+
''': "'",
|
|
36
|
+
'/': '/',
|
|
37
|
+
''': "'",
|
|
38
|
+
'/': '/',
|
|
39
|
+
''': "'",
|
|
40
|
+
'»': '»',
|
|
41
|
+
};
|
|
42
|
+
const ENTITY_RE = /&#x[0-9a-fA-F]+;|&#\d+;|&\w+;/g;
|
|
43
|
+
/**
|
|
44
|
+
* Decodes HTML entities in a string.
|
|
45
|
+
* Handles named entities (&, », etc.) and numeric/hex entities (/, ').
|
|
46
|
+
*/
|
|
47
|
+
export function decodeHtmlEntities(str) {
|
|
48
|
+
return str.replace(ENTITY_RE, (match) => {
|
|
49
|
+
if (HTML_ENTITIES[match])
|
|
50
|
+
return HTML_ENTITIES[match];
|
|
51
|
+
// Hex entity: &#xHH;
|
|
52
|
+
if (match.startsWith('&#x')) {
|
|
53
|
+
const code = parseInt(match.slice(3, -1), 16);
|
|
54
|
+
return isNaN(code) ? match : String.fromCharCode(code);
|
|
55
|
+
}
|
|
56
|
+
// Decimal entity: &#DD;
|
|
57
|
+
if (match.startsWith('&#')) {
|
|
58
|
+
const code = parseInt(match.slice(2, -1), 10);
|
|
59
|
+
return isNaN(code) ? match : String.fromCharCode(code);
|
|
60
|
+
}
|
|
61
|
+
return match;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Formats a byte count into a human-readable string.
|
|
66
|
+
* Examples: "0 B", "512 B", "15.0 KB", "5.0 MB"
|
|
67
|
+
*/
|
|
68
|
+
export function formatFileSize(bytes) {
|
|
69
|
+
if (bytes === 0)
|
|
70
|
+
return '0 B';
|
|
71
|
+
if (bytes < 1024)
|
|
72
|
+
return `${bytes} B`;
|
|
73
|
+
if (bytes < 1024 * 1024)
|
|
74
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
75
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Parses a human-readable file size string into bytes.
|
|
79
|
+
* Accepts: '2 KB', '5.0 MB', '512 B', '1024', etc.
|
|
80
|
+
* Returns 0 for invalid/unparseable input.
|
|
81
|
+
*/
|
|
82
|
+
export function parseFileSize(input) {
|
|
83
|
+
if (input == null)
|
|
84
|
+
return 0;
|
|
85
|
+
if (typeof input === 'number')
|
|
86
|
+
return input;
|
|
87
|
+
const trimmed = input.trim().toLowerCase();
|
|
88
|
+
if (!trimmed)
|
|
89
|
+
return 0;
|
|
90
|
+
const match = trimmed.match(/^([\d.]+)\s*(b|kb|mb|gb)?$/i);
|
|
91
|
+
if (!match)
|
|
92
|
+
return 0;
|
|
93
|
+
const value = parseFloat(match[1]);
|
|
94
|
+
if (isNaN(value))
|
|
95
|
+
return 0;
|
|
96
|
+
const unit = (match[2] || 'b').toLowerCase();
|
|
97
|
+
switch (unit) {
|
|
98
|
+
case 'b': return Math.round(value);
|
|
99
|
+
case 'kb': return Math.round(value * 1024);
|
|
100
|
+
case 'mb': return Math.round(value * 1024 * 1024);
|
|
101
|
+
case 'gb': return Math.round(value * 1024 * 1024 * 1024);
|
|
102
|
+
default: return Math.round(value);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Parses a T4 element key like "Title#2:1" into its parts.
|
|
107
|
+
* Returns null if the key doesn't match the expected format.
|
|
108
|
+
*/
|
|
109
|
+
export function parseElementKey(key) {
|
|
110
|
+
const match = key.match(/^(.+)#(\d+):(\d+)$/);
|
|
111
|
+
if (!match)
|
|
112
|
+
return null;
|
|
113
|
+
return { name: match[1], elementId: parseInt(match[2], 10), type: parseInt(match[3], 10) };
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Maps T4 status codes to friendly strings.
|
|
117
|
+
* Sections use 0–2; content and media also use 3 (draft).
|
|
118
|
+
*/
|
|
119
|
+
export const STATUS_MAP = {
|
|
120
|
+
0: 'approved',
|
|
121
|
+
1: 'pending',
|
|
122
|
+
2: 'inactive',
|
|
123
|
+
3: 'draft',
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
* Converts a numeric T4 status code to a friendly string.
|
|
127
|
+
*/
|
|
128
|
+
export function mapStatus(code) {
|
|
129
|
+
return STATUS_MAP[code] ?? `unknown (${code})`;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Maps friendly status strings to T4 numeric status codes.
|
|
133
|
+
* Sections use 0–2; content also uses 3 (draft).
|
|
134
|
+
*/
|
|
135
|
+
export const STATUS_CODES = {
|
|
136
|
+
approved: 0,
|
|
137
|
+
pending: 1,
|
|
138
|
+
inactive: 2,
|
|
139
|
+
draft: 3,
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* Maps T4 auth level codes to friendly user level strings.
|
|
143
|
+
*/
|
|
144
|
+
export const AUTH_LEVEL_MAP = {
|
|
145
|
+
0: 'admin',
|
|
146
|
+
40: 'power-user',
|
|
147
|
+
1: 'moderator',
|
|
148
|
+
2: 'contributor',
|
|
149
|
+
50: 'visitor',
|
|
150
|
+
};
|
|
151
|
+
/**
|
|
152
|
+
* Maps friendly user level strings to T4 auth level codes.
|
|
153
|
+
*/
|
|
154
|
+
export const AUTH_LEVEL_REVERSE = {
|
|
155
|
+
'admin': 0,
|
|
156
|
+
'power-user': 40,
|
|
157
|
+
'moderator': 1,
|
|
158
|
+
'contributor': 2,
|
|
159
|
+
'visitor': 50,
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* Recursively flattens a hierarchical group tree into a flat Map of id → name.
|
|
163
|
+
*/
|
|
164
|
+
export function flattenGroups(groups, map = new Map()) {
|
|
165
|
+
for (const g of groups) {
|
|
166
|
+
map.set(g.id, g.name);
|
|
167
|
+
if (Array.isArray(g.groupChildren) && g.groupChildren.length > 0) {
|
|
168
|
+
flattenGroups(g.groupChildren, map);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return map;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Resolves a file input (path, URL, Blob, or ReadableStream) to a Blob.
|
|
175
|
+
*/
|
|
176
|
+
export async function resolveFileToBlob(file) {
|
|
177
|
+
if (file instanceof Blob)
|
|
178
|
+
return file;
|
|
179
|
+
if (typeof file === 'string') {
|
|
180
|
+
if (file.startsWith('https://') || file.startsWith('http://')) {
|
|
181
|
+
const response = await fetch(file);
|
|
182
|
+
if (!response.ok) {
|
|
183
|
+
throw new Error(`Failed to fetch file from ${file}: ${response.status} ${response.statusText}`);
|
|
184
|
+
}
|
|
185
|
+
return await response.blob();
|
|
186
|
+
}
|
|
187
|
+
const { readFile } = await import('node:fs/promises');
|
|
188
|
+
const buffer = await readFile(file);
|
|
189
|
+
return new Blob([buffer]);
|
|
190
|
+
}
|
|
191
|
+
// ReadableStream — collect into buffer
|
|
192
|
+
const chunks = [];
|
|
193
|
+
for await (const chunk of file) {
|
|
194
|
+
chunks.push(new Uint8Array(chunk));
|
|
195
|
+
}
|
|
196
|
+
return new Blob(chunks);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Derives a filename from a file input (path, URL, Blob, ReadableStream, or { file, filename }).
|
|
200
|
+
*/
|
|
201
|
+
export function deriveFilename(input) {
|
|
202
|
+
if (typeof input === 'string') {
|
|
203
|
+
if (input.startsWith('https://') || input.startsWith('http://')) {
|
|
204
|
+
try {
|
|
205
|
+
return new URL(input).pathname.split('/').pop() || 'file';
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
return 'file';
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return input.replace(/\\/g, '/').split('/').pop() || 'file';
|
|
212
|
+
}
|
|
213
|
+
if (input instanceof Blob)
|
|
214
|
+
return 'file';
|
|
215
|
+
if (typeof input === 'object' && input !== null && 'file' in input) {
|
|
216
|
+
return input.filename
|
|
217
|
+
|| (typeof input.file === 'string' ? deriveFilename(input.file) : 'file');
|
|
218
|
+
}
|
|
219
|
+
// ReadableStream — no filename derivable
|
|
220
|
+
return 'file';
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Logs a warning message when T4_DEBUG=1 is set.
|
|
224
|
+
* Used for graceful degradation paths where errors are caught and fallback
|
|
225
|
+
* values are returned — the warning makes these visible during debugging.
|
|
226
|
+
*/
|
|
227
|
+
export function debugWarn(message, error) {
|
|
228
|
+
if (typeof process !== 'undefined' && process.env?.T4_DEBUG === '1') {
|
|
229
|
+
const detail = error instanceof Error ? error.message : error ? String(error) : '';
|
|
230
|
+
console.warn(`[T4 SDK] ${message}${detail ? `: ${detail}` : ''}`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Throws when running in a browser.
|
|
235
|
+
*
|
|
236
|
+
* The T4 API token is a full-privilege credential sent on every request. Bundling
|
|
237
|
+
* it into front-end code exposes it to anyone who opens devtools, so the SDK fails
|
|
238
|
+
* loudly at construction time — during development, when it's cheapest to fix —
|
|
239
|
+
* rather than silently shipping a leaked credential to production.
|
|
240
|
+
*
|
|
241
|
+
* There is no override. Detection deliberately requires both `window` and
|
|
242
|
+
* `window.document`, so genuine server-side runtimes without a DOM (Node, Deno,
|
|
243
|
+
* Bun, Cloudflare Workers) are unaffected.
|
|
244
|
+
*/
|
|
245
|
+
export function assertNotBrowser() {
|
|
246
|
+
const isBrowser = typeof window !== 'undefined'
|
|
247
|
+
&& typeof window.document !== 'undefined';
|
|
248
|
+
if (!isBrowser)
|
|
249
|
+
return;
|
|
250
|
+
throw new Error('T4Client cannot be used in a browser. The apiToken is a full-privilege ' +
|
|
251
|
+
'credential and anything in front-end code is publicly readable, so this would ' +
|
|
252
|
+
'expose it to every visitor.\n\n' +
|
|
253
|
+
'Call the T4 API from a server you control (an API route, serverless function, ' +
|
|
254
|
+
'or backend service) and have the browser talk to that instead.');
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Validates and normalises a base URL.
|
|
258
|
+
*
|
|
259
|
+
* - Throws if the value isn't a parseable absolute URL or doesn't use http/https.
|
|
260
|
+
* - Warns when the scheme is `http:`, because every request sends the API token
|
|
261
|
+
* in an `Authorization` header and plain HTTP transmits it in cleartext.
|
|
262
|
+
* - Strips trailing slashes so `baseUrl + path` never produces a double slash.
|
|
263
|
+
*/
|
|
264
|
+
export function normaliseBaseUrl(baseUrl) {
|
|
265
|
+
let parsed;
|
|
266
|
+
try {
|
|
267
|
+
parsed = new URL(baseUrl);
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
throw new Error(`T4Client baseUrl "${baseUrl}" is not a valid absolute URL. ` +
|
|
271
|
+
'Expected something like "https://mysite.edu/terminalfour/rs".');
|
|
272
|
+
}
|
|
273
|
+
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {
|
|
274
|
+
throw new Error(`T4Client baseUrl must use http or https, received "${parsed.protocol}".`);
|
|
275
|
+
}
|
|
276
|
+
if (parsed.protocol === 'http:') {
|
|
277
|
+
console.warn('[T4 SDK] baseUrl uses http:// — the API token will be sent in cleartext. ' +
|
|
278
|
+
'Use https:// unless you are testing against a local instance.');
|
|
279
|
+
}
|
|
280
|
+
return baseUrl.replace(/\/+$/, '');
|
|
281
|
+
}
|
|
282
|
+
/** Default cache TTL in milliseconds (5 minutes) */
|
|
283
|
+
export const DEFAULT_CACHE_TTL = 5 * 60 * 1000;
|
|
284
|
+
/**
|
|
285
|
+
* Global cache epoch. Incremented by `invalidateAllCaches()` to force
|
|
286
|
+
* all TTL-based caches to treat their entries as expired. Every cache
|
|
287
|
+
* records the epoch at write time; on read, if the current epoch is
|
|
288
|
+
* higher, the entry is stale regardless of its TTL.
|
|
289
|
+
*/
|
|
290
|
+
let cacheEpoch = 0;
|
|
291
|
+
/** Returns the current cache epoch. */
|
|
292
|
+
export function getCacheEpoch() {
|
|
293
|
+
return cacheEpoch;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Bumps the global cache epoch, causing all TTL-based caches to miss
|
|
297
|
+
* on their next read. This is the mechanism behind `T4Client.clearCache()`.
|
|
298
|
+
*/
|
|
299
|
+
export function invalidateAllCaches() {
|
|
300
|
+
cacheEpoch++;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* A Map with time-to-live expiration on entries.
|
|
304
|
+
* Entries are lazily evicted on access — expired entries return undefined.
|
|
305
|
+
* Respects the global cache epoch: entries written before an epoch bump are stale.
|
|
306
|
+
*/
|
|
307
|
+
export class TtlMap {
|
|
308
|
+
constructor(ttl = DEFAULT_CACHE_TTL) {
|
|
309
|
+
this.entries = new Map();
|
|
310
|
+
this.ttl = ttl;
|
|
311
|
+
}
|
|
312
|
+
get(key) {
|
|
313
|
+
const entry = this.entries.get(key);
|
|
314
|
+
if (!entry)
|
|
315
|
+
return undefined;
|
|
316
|
+
if (entry.epoch < cacheEpoch || Date.now() > entry.expiresAt) {
|
|
317
|
+
this.entries.delete(key);
|
|
318
|
+
return undefined;
|
|
319
|
+
}
|
|
320
|
+
return entry.value;
|
|
321
|
+
}
|
|
322
|
+
set(key, value) {
|
|
323
|
+
this.entries.set(key, { value, expiresAt: Date.now() + this.ttl, epoch: cacheEpoch });
|
|
324
|
+
}
|
|
325
|
+
clear() {
|
|
326
|
+
this.entries.clear();
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* A single-value cache with TTL expiration.
|
|
331
|
+
* Stores a promise that resolves to the cached value.
|
|
332
|
+
* Respects the global cache epoch: entries written before an epoch bump are stale.
|
|
333
|
+
*/
|
|
334
|
+
export class TtlValue {
|
|
335
|
+
constructor(ttl = DEFAULT_CACHE_TTL) {
|
|
336
|
+
this.entry = null;
|
|
337
|
+
this.ttl = ttl;
|
|
338
|
+
}
|
|
339
|
+
get() {
|
|
340
|
+
if (!this.entry)
|
|
341
|
+
return undefined;
|
|
342
|
+
if (this.entry.epoch < cacheEpoch || Date.now() > this.entry.expiresAt) {
|
|
343
|
+
this.entry = null;
|
|
344
|
+
return undefined;
|
|
345
|
+
}
|
|
346
|
+
return this.entry.value;
|
|
347
|
+
}
|
|
348
|
+
set(value) {
|
|
349
|
+
this.entry = { value, expiresAt: Date.now() + this.ttl, epoch: cacheEpoch };
|
|
350
|
+
}
|
|
351
|
+
clear() {
|
|
352
|
+
this.entry = null;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"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"}
|
package/docs/channels.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Channels
|
|
2
|
+
|
|
3
|
+
Use `t4.channels` to list channel summaries, inspect channel configuration, and publish a channel.
|
|
4
|
+
|
|
5
|
+
## List channels
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
const channels = await t4.channels.list();
|
|
9
|
+
// [{ id: 1, name: 'Sample Site', description: '...', rootSectionId: 233 }]
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
A channel with microsites includes a `microSites` array. The property is omitted when the channel has no microsites.
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
const channel = channels.find(item => item.microSites);
|
|
16
|
+
if (channel?.microSites) {
|
|
17
|
+
for (const microsite of channel.microSites) {
|
|
18
|
+
console.log(microsite.id, microsite.name, microsite.rootSectionId, microsite.parentId);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Get channel details
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
const channel = await t4.channels.get(1);
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
| Property | Example or meaning |
|
|
30
|
+
|---|---|
|
|
31
|
+
| `name` | `'Sample Site'` |
|
|
32
|
+
| `description` | Channel description |
|
|
33
|
+
| `defaultLayout` | `'text/html'` |
|
|
34
|
+
| `defaultLanguage` | `'en'` |
|
|
35
|
+
| `rootSectionId` | `233` |
|
|
36
|
+
| `fileOutputPath` | `'/web/stage/htdocs/'` |
|
|
37
|
+
| `indexFileName` | `'index.php'` |
|
|
38
|
+
| `baseHref` | `'https://example.com'` |
|
|
39
|
+
| `siteRoot` | `'/'` |
|
|
40
|
+
| `publishUrl` | `'https://example.com'` |
|
|
41
|
+
| `defaultFullTextLayout` | Default fulltext layout |
|
|
42
|
+
| `fullTextExtension` | Fulltext file extension |
|
|
43
|
+
| `fileExtensions` | `['php', 'xml', 'json']`, sorted by priority |
|
|
44
|
+
| `languages` | `[{ code: 'en', name: 'English', charset: 'ISO-8859-15' }]` |
|
|
45
|
+
| `microSites` | `[{ id: 6, name: 'Microsite Test' }]` or `undefined` |
|
|
46
|
+
|
|
47
|
+
## Publish a channel
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
const channel = await t4.channels.get(1);
|
|
51
|
+
await channel.publish();
|
|
52
|
+
|
|
53
|
+
await channel.publish({
|
|
54
|
+
includeArchives: true,
|
|
55
|
+
overridePublishPeriodRestriction: true,
|
|
56
|
+
language: 'fr',
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
**Previous:** [Media Types](./media-types.md) · **Next:** [Navigation](./navigation.md)
|