ferst-core 0.9.1 → 0.9.2
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/bin/cms-config.mjs +44 -7
- package/cms/config.template.yml +3 -1
- package/package.json +1 -1
package/bin/cms-config.mjs
CHANGED
|
@@ -108,18 +108,47 @@ export function deploymentBranch() {
|
|
|
108
108
|
return 'main';
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
/** Ferst's managed GitHub org: its sites are on the Basic plan. */
|
|
112
|
+
const MANAGED_OWNER = 'myai4webdev';
|
|
113
|
+
|
|
114
|
+
/** The Pages collection's description on each plan. */
|
|
115
|
+
const PAGES_DESCRIPTION = {
|
|
116
|
+
basic: "See each page and request a change — our team makes it and sends it back for you to check. You don't edit the page layout here.",
|
|
117
|
+
free: "You're on the free plan: you look after this site yourself and change its pages in your own repository. Asking the Ferst team to make changes for you comes with the Basic plan.",
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* The site's plan, for what its CMS offers. Requests (the Ferst team making a change for the
|
|
122
|
+
* site's people) come with the Basic plan: a managed site. A self-managed site, the client's
|
|
123
|
+
* own repo, is on the free plan and makes its own changes. The plan the platform records in
|
|
124
|
+
* `ferst-site.json` wins; otherwise the repo's owner decides. Unknown keeps the requests field:
|
|
125
|
+
* the platform refuses a free-plan site's request anyway.
|
|
126
|
+
* @param {string} repo owner/name
|
|
127
|
+
* @param {{ plan?: string }} [site] the parsed ferst-site.json
|
|
128
|
+
* @returns {'basic' | 'free'}
|
|
129
|
+
*/
|
|
130
|
+
export function planFor(repo, site = {}) {
|
|
131
|
+
if (site && (site.plan === 'basic' || site.plan === 'free')) return site.plan;
|
|
132
|
+
const owner = String(repo ?? '').split('/')[0].trim().toLowerCase();
|
|
133
|
+
if (!owner) return 'basic';
|
|
134
|
+
return owner === MANAGED_OWNER ? 'basic' : 'free';
|
|
135
|
+
}
|
|
136
|
+
|
|
111
137
|
/**
|
|
112
|
-
* Fill the config template's placeholders. Pure — unit-testable.
|
|
138
|
+
* Fill the config template's placeholders. Pure — unit-testable. On the free plan the
|
|
139
|
+
* `# ferst:requests` … `# /ferst:requests` block (the pages' "Requested changes") is left out.
|
|
113
140
|
* @param {string} tpl the template contents
|
|
114
|
-
* @param {{ repo: string, base: string, branch: string }} vars
|
|
141
|
+
* @param {{ repo: string, base: string, branch: string, plan?: 'basic' | 'free' }} vars
|
|
115
142
|
* @returns {string}
|
|
116
143
|
*/
|
|
117
|
-
export function fillConfig(tpl, { repo, base, branch }) {
|
|
118
|
-
const
|
|
144
|
+
export function fillConfig(tpl, { repo, base, branch, plan = 'basic' }) {
|
|
145
|
+
const forPlan = plan === 'free' ? tpl.replace(/^[ \t]*# ferst:requests\b[\s\S]*?^[ \t]*# \/ferst:requests[^\n]*\n/m, '') : tpl;
|
|
146
|
+
const out = forPlan
|
|
119
147
|
.split('__REPO__').join(repo)
|
|
120
148
|
.split('__API_ROOT__').join(`${base}/git`)
|
|
121
149
|
.split('__BASE_URL__').join(base)
|
|
122
|
-
.split('__BRANCH__').join(branch)
|
|
150
|
+
.split('__BRANCH__').join(branch)
|
|
151
|
+
.split('__PAGES_DESCRIPTION__').join(PAGES_DESCRIPTION[plan] ?? PAGES_DESCRIPTION.basic);
|
|
123
152
|
const leftover = out.match(/__[A-Z][A-Z_]*__/);
|
|
124
153
|
if (leftover) {
|
|
125
154
|
throw new Error(`ferst-cms-config: unfilled placeholder ${leftover[0]} — add it to the filler.`);
|
|
@@ -147,9 +176,17 @@ function main() {
|
|
|
147
176
|
process.exit(1);
|
|
148
177
|
}
|
|
149
178
|
|
|
179
|
+
let site = {};
|
|
180
|
+
try {
|
|
181
|
+
site = JSON.parse(readFileSync(resolve(process.cwd(), 'ferst-site.json'), 'utf8')) ?? {};
|
|
182
|
+
} catch {
|
|
183
|
+
/* no ferst-site.json: the repo's owner decides the plan */
|
|
184
|
+
}
|
|
185
|
+
const plan = planFor(repo, site);
|
|
186
|
+
|
|
150
187
|
let out;
|
|
151
188
|
try {
|
|
152
|
-
out = fillConfig(tpl, { repo, base, branch });
|
|
189
|
+
out = fillConfig(tpl, { repo, base, branch, plan });
|
|
153
190
|
} catch (e) {
|
|
154
191
|
console.error(String(e.message ?? e));
|
|
155
192
|
process.exit(1);
|
|
@@ -157,7 +194,7 @@ function main() {
|
|
|
157
194
|
|
|
158
195
|
mkdirSync(dirname(outPath), { recursive: true });
|
|
159
196
|
writeFileSync(outPath, out);
|
|
160
|
-
console.log(`ferst-cms-config: wrote ${outPath} (repo=${repo}, branch="${branch}", base=${base})`);
|
|
197
|
+
console.log(`ferst-cms-config: wrote ${outPath} (repo=${repo}, branch="${branch}", base=${base}, plan=${plan})`);
|
|
161
198
|
}
|
|
162
199
|
|
|
163
200
|
// Run when invoked directly as a bin — including via npm's node_modules/.bin symlink.
|
package/cms/config.template.yml
CHANGED
|
@@ -234,7 +234,7 @@ collections:
|
|
|
234
234
|
- name: pages
|
|
235
235
|
label: Pages
|
|
236
236
|
label_singular: Page
|
|
237
|
-
description: "
|
|
237
|
+
description: "__PAGES_DESCRIPTION__"
|
|
238
238
|
folder: src/content/pages
|
|
239
239
|
extension: json
|
|
240
240
|
format: json
|
|
@@ -244,6 +244,7 @@ collections:
|
|
|
244
244
|
identifier_field: title
|
|
245
245
|
fields:
|
|
246
246
|
- { name: title, label: Page title, widget: string }
|
|
247
|
+
# ferst:requests (the Basic plan only: bin/cms-config.mjs leaves it out on the free plan)
|
|
247
248
|
- name: requests
|
|
248
249
|
label: Requested changes
|
|
249
250
|
label_singular: Request
|
|
@@ -258,6 +259,7 @@ collections:
|
|
|
258
259
|
- { name: issue, widget: hidden, required: false }
|
|
259
260
|
- { name: by, widget: hidden, required: false }
|
|
260
261
|
- { name: at, widget: hidden, required: false }
|
|
262
|
+
# /ferst:requests
|
|
261
263
|
- { name: description, label: SEO description, widget: hidden, required: false }
|
|
262
264
|
- { name: heroImage, widget: hidden, required: false }
|
|
263
265
|
- { name: align, widget: hidden, required: false }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ferst-core",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Ferst Core — the shared, brand-agnostic client-site system: Astro components, layouts, content schemas, the layered config resolver, and a neutral styling architecture that every client overrides.",
|
|
6
6
|
"license": "BUSL-1.1",
|