@notionx/create-notionx-app 1.0.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 +139 -0
- package/dist/answers.js +332 -0
- package/dist/answers.js.map +1 -0
- package/dist/cli-notionx.js +388 -0
- package/dist/cli-notionx.js.map +1 -0
- package/dist/cli-notionx.test.js +277 -0
- package/dist/cli-notionx.test.js.map +1 -0
- package/dist/diff.js +40 -0
- package/dist/diff.js.map +1 -0
- package/dist/diff.test.js +90 -0
- package/dist/diff.test.js.map +1 -0
- package/dist/index.js +99 -0
- package/dist/index.js.map +1 -0
- package/dist/locale-add/apply.js +39 -0
- package/dist/locale-add/apply.js.map +1 -0
- package/dist/locale-add/format.js +38 -0
- package/dist/locale-add/format.js.map +1 -0
- package/dist/locale-add/list.js +44 -0
- package/dist/locale-add/list.js.map +1 -0
- package/dist/locale-add/list.test.js +45 -0
- package/dist/locale-add/list.test.js.map +1 -0
- package/dist/locale-add/plan.js +128 -0
- package/dist/locale-add/plan.js.map +1 -0
- package/dist/locale-add/validate.js +46 -0
- package/dist/locale-add/validate.js.map +1 -0
- package/dist/metadata.js +41 -0
- package/dist/metadata.js.map +1 -0
- package/dist/notion-translation-sources/apply.js +61 -0
- package/dist/notion-translation-sources/apply.js.map +1 -0
- package/dist/notion-translation-sources/index.js +3 -0
- package/dist/notion-translation-sources/index.js.map +1 -0
- package/dist/notion-translation-sources/plan.js +33 -0
- package/dist/notion-translation-sources/plan.js.map +1 -0
- package/dist/notionx-source.js +142 -0
- package/dist/notionx-source.js.map +1 -0
- package/dist/notionx-source.test.js +144 -0
- package/dist/notionx-source.test.js.map +1 -0
- package/dist/password.js +18 -0
- package/dist/password.js.map +1 -0
- package/dist/presets.js +83 -0
- package/dist/presets.js.map +1 -0
- package/dist/presets.test.js +50 -0
- package/dist/presets.test.js.map +1 -0
- package/dist/prompt.js +218 -0
- package/dist/prompt.js.map +1 -0
- package/dist/provision/cloudflare.js +236 -0
- package/dist/provision/cloudflare.js.map +1 -0
- package/dist/provision/dependencies.js +219 -0
- package/dist/provision/dependencies.js.map +1 -0
- package/dist/provision/index.js +681 -0
- package/dist/provision/index.js.map +1 -0
- package/dist/provision/index.test.js +54 -0
- package/dist/provision/index.test.js.map +1 -0
- package/dist/provision/inspect.js +109 -0
- package/dist/provision/inspect.js.map +1 -0
- package/dist/provision/inspect.test.js +75 -0
- package/dist/provision/inspect.test.js.map +1 -0
- package/dist/provision/notion.js +1981 -0
- package/dist/provision/notion.js.map +1 -0
- package/dist/provision/notion.test.js +542 -0
- package/dist/provision/notion.test.js.map +1 -0
- package/dist/provision/ntn-credentials.js +198 -0
- package/dist/provision/ntn-credentials.js.map +1 -0
- package/dist/provision/options.js +15 -0
- package/dist/provision/options.js.map +1 -0
- package/dist/provision/password-hash.js +78 -0
- package/dist/provision/password-hash.js.map +1 -0
- package/dist/provision/prompts.js +115 -0
- package/dist/provision/prompts.js.map +1 -0
- package/dist/provision/repair.js +48 -0
- package/dist/provision/repair.js.map +1 -0
- package/dist/provision/repair.test.js +141 -0
- package/dist/provision/repair.test.js.map +1 -0
- package/dist/provision/shell.js +84 -0
- package/dist/provision/shell.js.map +1 -0
- package/dist/provision/wire.js +78 -0
- package/dist/provision/wire.js.map +1 -0
- package/dist/registry/doctor.js +181 -0
- package/dist/registry/doctor.js.map +1 -0
- package/dist/registry/doctor.test.js +180 -0
- package/dist/registry/doctor.test.js.map +1 -0
- package/dist/registry/install.js +217 -0
- package/dist/registry/install.js.map +1 -0
- package/dist/registry/install.test.js +168 -0
- package/dist/registry/install.test.js.map +1 -0
- package/dist/registry/load-registry.js +24 -0
- package/dist/registry/load-registry.js.map +1 -0
- package/dist/registry/load-registry.test.js +59 -0
- package/dist/registry/load-registry.test.js.map +1 -0
- package/dist/registry/migration-planner.js +204 -0
- package/dist/registry/migration-planner.js.map +1 -0
- package/dist/registry/migration-planner.test.js +340 -0
- package/dist/registry/migration-planner.test.js.map +1 -0
- package/dist/registry/migrations-store.js +125 -0
- package/dist/registry/migrations-store.js.map +1 -0
- package/dist/registry/migrations-store.test.js +163 -0
- package/dist/registry/migrations-store.test.js.map +1 -0
- package/dist/registry/migrations-types.js +25 -0
- package/dist/registry/migrations-types.js.map +1 -0
- package/dist/registry/project-meta.js +84 -0
- package/dist/registry/project-meta.js.map +1 -0
- package/dist/registry/registry-items.js +354 -0
- package/dist/registry/registry-items.js.map +1 -0
- package/dist/registry/registry-items.test.js +99 -0
- package/dist/registry/registry-items.test.js.map +1 -0
- package/dist/registry/registry-store.js +232 -0
- package/dist/registry/registry-store.js.map +1 -0
- package/dist/registry/registry-store.test.js +136 -0
- package/dist/registry/registry-store.test.js.map +1 -0
- package/dist/registry/registry-types.js +18 -0
- package/dist/registry/registry-types.js.map +1 -0
- package/dist/registry/registry-types.test.js +146 -0
- package/dist/registry/registry-types.test.js.map +1 -0
- package/dist/registry/render-content-source-files.js +158 -0
- package/dist/registry/render-content-source-files.js.map +1 -0
- package/dist/registry/render-multi-source.js +296 -0
- package/dist/registry/render-multi-source.js.map +1 -0
- package/dist/registry/render-multi-source.test.js +110 -0
- package/dist/registry/render-multi-source.test.js.map +1 -0
- package/dist/registry/text-utils.js +42 -0
- package/dist/registry/text-utils.js.map +1 -0
- package/dist/registry/uninstall.js +250 -0
- package/dist/registry/uninstall.js.map +1 -0
- package/dist/registry/uninstall.test.js +264 -0
- package/dist/registry/uninstall.test.js.map +1 -0
- package/dist/registry/update.js +280 -0
- package/dist/registry/update.js.map +1 -0
- package/dist/registry/update.test.js +229 -0
- package/dist/registry/update.test.js.map +1 -0
- package/dist/render.js +549 -0
- package/dist/render.js.map +1 -0
- package/dist/render.test.js +414 -0
- package/dist/render.test.js.map +1 -0
- package/dist/templates/.dev.vars.example.tmpl +32 -0
- package/dist/templates/.gitignore.tmpl +58 -0
- package/dist/templates/README.md.tmpl +417 -0
- package/dist/templates/app/[slug]/page.tsx.tmpl +55 -0
- package/dist/templates/app/admin/account/page.tsx.tmpl +18 -0
- package/dist/templates/app/admin/content-models/page.tsx.tmpl +6 -0
- package/dist/templates/app/admin/layout.tsx.tmpl +90 -0
- package/dist/templates/app/admin/loading.tsx.tmpl +6 -0
- package/dist/templates/app/admin/page.tsx.tmpl +17 -0
- package/dist/templates/app/api/auth/google/callback/route.ts.tmpl +3 -0
- package/dist/templates/app/api/auth/google/route.ts.tmpl +3 -0
- package/dist/templates/app/api/auth/verify-email/route.ts.tmpl +3 -0
- package/dist/templates/app/api/auth/viewer/route.ts.tmpl +3 -0
- package/dist/templates/app/api/health/route.ts.tmpl +3 -0
- package/dist/templates/app/api/{{contentSourceId}}/[slug]/route.ts.tmpl +27 -0
- package/dist/templates/app/api/{{contentSourceId}}/route.ts.tmpl +18 -0
- package/dist/templates/app/globals.css.tmpl +109 -0
- package/dist/templates/app/layout.tsx.tmpl +56 -0
- package/dist/templates/app/login/page.tsx.tmpl +154 -0
- package/dist/templates/app/page.fallback.tsx.tmpl +31 -0
- package/dist/templates/app/page.tsx.tmpl +42 -0
- package/dist/templates/app/register/page.tsx.tmpl +138 -0
- package/dist/templates/app/{{contentSourceListPath}}/[slug]/page.tsx.tmpl +113 -0
- package/dist/templates/app/{{contentSourceListPath}}/page.tsx.tmpl +74 -0
- package/dist/templates/components/content/post-card.tsx.tmpl +80 -0
- package/dist/templates/components/notion-blocks.tsx.tmpl +668 -0
- package/dist/templates/components/page-blocks/feature-grid-block.tsx.tmpl +68 -0
- package/dist/templates/components/page-blocks/hero-block.tsx.tmpl +73 -0
- package/dist/templates/components/page-blocks/latest-posts-block.tsx.tmpl +59 -0
- package/dist/templates/components/page-blocks/story-block.tsx.tmpl +70 -0
- package/dist/templates/components/page-blocks.fallback.tsx.tmpl +17 -0
- package/dist/templates/components/page-blocks.tsx.tmpl +32 -0
- package/dist/templates/components/search/search-dialog.tsx.tmpl +171 -0
- package/dist/templates/components/site/locale-switcher.tsx.tmpl +65 -0
- package/dist/templates/components/site/site-footer.tsx.tmpl +106 -0
- package/dist/templates/components/site/site-header.tsx.tmpl +80 -0
- package/dist/templates/components/site/site-shell.tsx.tmpl +20 -0
- package/dist/templates/components/site/theme-bootstrap.tsx.tmpl +51 -0
- package/dist/templates/components/theme-provider.tsx.tmpl +14 -0
- package/dist/templates/components/theme-toggle.tsx.tmpl +38 -0
- package/dist/templates/components/ui/accordion.tsx.tmpl +56 -0
- package/dist/templates/components/ui/alert.tsx.tmpl +59 -0
- package/dist/templates/components/ui/aspect-ratio.tsx.tmpl +8 -0
- package/dist/templates/components/ui/avatar.tsx.tmpl +44 -0
- package/dist/templates/components/ui/badge.tsx.tmpl +33 -0
- package/dist/templates/components/ui/button.tsx.tmpl +56 -0
- package/dist/templates/components/ui/card.tsx.tmpl +61 -0
- package/dist/templates/components/ui/checkbox.tsx.tmpl +28 -0
- package/dist/templates/components/ui/dialog.tsx.tmpl +104 -0
- package/dist/templates/components/ui/dropdown-menu.tsx.tmpl +183 -0
- package/dist/templates/components/ui/input.tsx.tmpl +21 -0
- package/dist/templates/components/ui/label.tsx.tmpl +25 -0
- package/dist/templates/components/ui/popover.tsx.tmpl +30 -0
- package/dist/templates/components/ui/radio-group.tsx.tmpl +44 -0
- package/dist/templates/components/ui/select.tsx.tmpl +150 -0
- package/dist/templates/components/ui/separator.tsx.tmpl +30 -0
- package/dist/templates/components/ui/sheet.tsx.tmpl +125 -0
- package/dist/templates/components/ui/skeleton.tsx.tmpl +15 -0
- package/dist/templates/components/ui/sonner.tsx.tmpl +30 -0
- package/dist/templates/components/ui/switch.tsx.tmpl +29 -0
- package/dist/templates/components/ui/table.tsx.tmpl +107 -0
- package/dist/templates/components/ui/tabs.tsx.tmpl +55 -0
- package/dist/templates/components/ui/textarea.tsx.tmpl +24 -0
- package/dist/templates/components/ui/tooltip.tsx.tmpl +30 -0
- package/dist/templates/components.json.tmpl +21 -0
- package/dist/templates/env.d.ts.tmpl +32 -0
- package/dist/templates/lib/admin/actions.ts.tmpl +43 -0
- package/dist/templates/lib/admin/context.tsx.tmpl +209 -0
- package/dist/templates/lib/admin/nav.ts.tmpl +23 -0
- package/dist/templates/lib/auth.config.fallback.ts.tmpl +10 -0
- package/dist/templates/lib/auth.config.ts.tmpl +45 -0
- package/dist/templates/lib/blocks/translations.ts.tmpl +44 -0
- package/dist/templates/lib/blog/translations.ts.tmpl +52 -0
- package/dist/templates/lib/content/models.ts.tmpl +53 -0
- package/dist/templates/lib/i18n/config.ts.tmpl +18 -0
- package/dist/templates/lib/i18n/index.ts.tmpl +1 -0
- package/dist/templates/lib/locale-contract/built-in.ts.tmpl +19 -0
- package/dist/templates/lib/locale-contract/index.ts.tmpl +3 -0
- package/dist/templates/lib/locale-contract/paths.ts.tmpl +29 -0
- package/dist/templates/lib/pages/model.ts.tmpl +16 -0
- package/dist/templates/lib/pages/source.ts.tmpl +566 -0
- package/dist/templates/lib/pages/translations.ts.tmpl +34 -0
- package/dist/templates/lib/search/config.fallback.ts.tmpl +11 -0
- package/dist/templates/lib/search/config.ts.tmpl +25 -0
- package/dist/templates/lib/site/config.ts.tmpl +120 -0
- package/dist/templates/lib/site/request-env.ts.tmpl +71 -0
- package/dist/templates/lib/site/settings.fallback.ts.tmpl +21 -0
- package/dist/templates/lib/site/settings.ts.tmpl +320 -0
- package/dist/templates/lib/site/translations.ts.tmpl +30 -0
- package/dist/templates/lib/utils.ts.tmpl +9 -0
- package/dist/templates/migrations/0001_init.sql.tmpl +57 -0
- package/dist/templates/migrations/0002_admin_seed.sql.tmpl +30 -0
- package/dist/templates/migrations/0003_search_index.sql.tmpl +29 -0
- package/dist/templates/next.config.ts.tmpl +18 -0
- package/dist/templates/package.json.tmpl +40 -0
- package/dist/templates/shims/cloudflare-workers-empty.mjs +4 -0
- package/dist/templates/shims/next-headers-empty.mjs +4 -0
- package/dist/templates/tests/smoke.test.ts.tmpl +83 -0
- package/dist/templates/tsconfig.json.tmpl +31 -0
- package/dist/templates/vite.config.ts.tmpl +53 -0
- package/dist/templates/vitest.config.ts.tmpl +13 -0
- package/dist/templates/worker/index.ts.tmpl +52 -0
- package/dist/templates/wrangler.jsonc.tmpl +44 -0
- package/dist/ui-presets.js +60 -0
- package/dist/ui-presets.js.map +1 -0
- package/package.json +60 -0
package/dist/render.js
ADDED
|
@@ -0,0 +1,549 @@
|
|
|
1
|
+
// packages/create-notionx-app/src/render.ts
|
|
2
|
+
//
|
|
3
|
+
// File renderer for `create-notionx-app`. Walks the `src/templates/`
|
|
4
|
+
// directory, copies static files verbatim, and renders `.tmpl` files
|
|
5
|
+
// with simple `{{token}}` interpolation. The token map is derived
|
|
6
|
+
// from the prompt answers.
|
|
7
|
+
import { promises as fs } from "node:fs";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import { siteComponentNames, siteDependencyEntries } from "./presets.js";
|
|
10
|
+
import { hashPasswordForScaffold } from "./provision/password-hash.js";
|
|
11
|
+
import { buildInitialRegistryManifest, writeRegistryManifest, } from "./registry/registry-store.js";
|
|
12
|
+
import { buildMultiSourceTokenMap } from "./registry/render-multi-source.js";
|
|
13
|
+
import { toCamel } from "./registry/text-utils.js";
|
|
14
|
+
import { uiComponents } from "./ui-presets.js";
|
|
15
|
+
/** Local-part of an email, used as the default display name. */
|
|
16
|
+
function localPart(email) {
|
|
17
|
+
const at = email.indexOf("@");
|
|
18
|
+
return at > 0 ? email.slice(0, at) : email;
|
|
19
|
+
}
|
|
20
|
+
async function buildTokenMap(answers, scaffoldVersion) {
|
|
21
|
+
const id = answers.contentSource.id;
|
|
22
|
+
const isBlog = id === "blog";
|
|
23
|
+
// Build the field map block that the generated `defineContentSource`
|
|
24
|
+
// call interpolates. Indent every key/value so the call stays
|
|
25
|
+
// readable inside the `fields: { ... }` object literal.
|
|
26
|
+
const fieldMapLines = answers.contentSource.fields.map((f) => {
|
|
27
|
+
const key = f.key;
|
|
28
|
+
const notionName = JSON.stringify(f.notionName);
|
|
29
|
+
return ` ${key}: ${notionName},`;
|
|
30
|
+
});
|
|
31
|
+
const fieldMapBlock = fieldMapLines.join("\n");
|
|
32
|
+
// Hash the admin password with the same algorithm that
|
|
33
|
+
// `@notionx/core`'s `hashPassword` uses, so the generated
|
|
34
|
+
// `0002_admin_seed.sql` produces a row that `verifyPassword` can
|
|
35
|
+
// check on first login. 100k PBKDF2 iterations takes ~200ms on
|
|
36
|
+
// modern hardware — visible in the spinner, worth the wait.
|
|
37
|
+
const adminPasswordHash = await hashPasswordForScaffold(answers.adminPassword);
|
|
38
|
+
const uiComponentNames = uiComponents();
|
|
39
|
+
return {
|
|
40
|
+
projectName: answers.projectName,
|
|
41
|
+
projectNameLower: answers.projectName.toLowerCase(),
|
|
42
|
+
targetDir: answers.targetDir,
|
|
43
|
+
defaultLocale: answers.defaultLocale,
|
|
44
|
+
supportedLocales: answers.supportedLocales.join(", "),
|
|
45
|
+
supportedLocalesJson: JSON.stringify(answers.supportedLocales),
|
|
46
|
+
notionxSource: answers.notionxSource,
|
|
47
|
+
createNotionxAppVersion: `^${scaffoldVersion}`,
|
|
48
|
+
contentSourceId: id,
|
|
49
|
+
contentSourceTitle: answers.contentSource.title,
|
|
50
|
+
contentSourceKind: '"article"',
|
|
51
|
+
contentSourceListPath: `/${id}`,
|
|
52
|
+
contentSourceDetailPath: `/${id}/[slug]`,
|
|
53
|
+
contentSourceApiPath: `/api/${id}`,
|
|
54
|
+
contentSourceFields: fieldMapBlock,
|
|
55
|
+
contentSourceVarName: `${toCamel(id)}Source`,
|
|
56
|
+
contentSourceConstName: `${toCamel(id)}ContentModel`,
|
|
57
|
+
contentSourceNavLabel: answers.contentSource.title,
|
|
58
|
+
contentSourcePluralName: `${answers.contentSource.title}s`,
|
|
59
|
+
contentSourceListTitle: answers.contentSource.title,
|
|
60
|
+
contentSourceListDescription: isBlog
|
|
61
|
+
? "Blog posts backed by Notion metadata and page body content."
|
|
62
|
+
: `${answers.contentSource.title} entries backed by Notion.`,
|
|
63
|
+
contentSourceEmptyState: isBlog
|
|
64
|
+
? "No blog posts published yet."
|
|
65
|
+
: `No ${answers.contentSource.title.toLowerCase()} entries yet.`,
|
|
66
|
+
contentSourceRichBlocks: isBlog ? "true" : "false",
|
|
67
|
+
contentSourceCoverImages: isBlog ? "true" : "false",
|
|
68
|
+
fieldList: answers.contentSource.fields.map((f) => f.key).join(", "),
|
|
69
|
+
adminEmail: answers.adminEmail,
|
|
70
|
+
adminName: localPart(answers.adminEmail),
|
|
71
|
+
adminPasswordHash,
|
|
72
|
+
dependenciesBlock: buildDependenciesBlock(answers.notionxSource),
|
|
73
|
+
uiComponentList: uiComponentNames.map((name) => `\`${name}\``).join(", "),
|
|
74
|
+
uiComponents: uiComponentNames,
|
|
75
|
+
// Multi-source tokens: the scaffold flow always describes exactly
|
|
76
|
+
// one content source (the "first" one), so we synthesise a
|
|
77
|
+
// single-item InstalledItem list and delegate to the multi-source
|
|
78
|
+
// builder. `notionx add` will call `buildMultiSourceTokenMap`
|
|
79
|
+
// directly with the project's full installed list.
|
|
80
|
+
//
|
|
81
|
+
// The `MultiSourceTokenMap` returns `contentSourceSourcesBlock`
|
|
82
|
+
// (the full `defineContentSource` block). The legacy
|
|
83
|
+
// `contentSourceSourcesVarNames` token (used by the
|
|
84
|
+
// `contentSources = [...]` array) is derived from the
|
|
85
|
+
// comma-joined variable names embedded in that block.
|
|
86
|
+
...(() => {
|
|
87
|
+
const multi = buildMultiSourceTokenMap({
|
|
88
|
+
project: {
|
|
89
|
+
projectName: answers.projectName,
|
|
90
|
+
targetDir: answers.targetDir,
|
|
91
|
+
defaultLocale: answers.defaultLocale,
|
|
92
|
+
supportedLocales: answers.supportedLocales,
|
|
93
|
+
notionxSource: answers.notionxSource,
|
|
94
|
+
adminEmail: answers.adminEmail,
|
|
95
|
+
adminPassword: answers.adminPassword,
|
|
96
|
+
scaffoldVersion,
|
|
97
|
+
},
|
|
98
|
+
installed: [
|
|
99
|
+
{
|
|
100
|
+
id: answers.contentSource.id,
|
|
101
|
+
kind: "content-source",
|
|
102
|
+
version: 1,
|
|
103
|
+
source: { kind: "official", name: "@notionx/official" },
|
|
104
|
+
params: {
|
|
105
|
+
contentSourceId: answers.contentSource.id,
|
|
106
|
+
...(isBlog ? {} : { basePath: `/${answers.contentSource.id}` }),
|
|
107
|
+
},
|
|
108
|
+
installedAt: new Date(0).toISOString(),
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
internalSources: {
|
|
112
|
+
siteSettings: answers.enableSiteSettings,
|
|
113
|
+
blocks: answers.enableBlocks,
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
return {
|
|
117
|
+
contentSourceDeclarations: multi.contentSourceDeclarations,
|
|
118
|
+
contentSourceSourcesVarNames: multi.contentSourceSourcesVarNames,
|
|
119
|
+
internalSourceDeclarations: multi.internalSourceDeclarations,
|
|
120
|
+
internalSourceVarNames: multi.internalSourceVarNames,
|
|
121
|
+
};
|
|
122
|
+
})(),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Build the `dependencies` block that goes into the generated
|
|
127
|
+
* `package.json`. The block is a JSON-style object body (4-space
|
|
128
|
+
* indent, no trailing comma) so it can be dropped between `{` and
|
|
129
|
+
* `}` in the template.
|
|
130
|
+
*
|
|
131
|
+
* The base dependency set is the union of every package the
|
|
132
|
+
* rendered components need. It is augmented by the preset's
|
|
133
|
+
* declared extras (e.g. `@radix-ui/react-accordion` for the
|
|
134
|
+
* `site` preset), filtered against the base set so we never emit
|
|
135
|
+
* duplicate keys.
|
|
136
|
+
*/
|
|
137
|
+
function buildDependenciesBlock(notionxSource) {
|
|
138
|
+
// The base dependency set — every project needs these regardless
|
|
139
|
+
// of which UI components it vendors. Keep this list stable: it is
|
|
140
|
+
// the floor of every generated project.
|
|
141
|
+
const baseDependencies = [
|
|
142
|
+
["@notionx/core", notionxSource],
|
|
143
|
+
["class-variance-authority", "^0.7.1"],
|
|
144
|
+
["clsx", "^2.1.1"],
|
|
145
|
+
["lucide-react", "^0.460.0"],
|
|
146
|
+
["next", "16.2.7"],
|
|
147
|
+
["next-themes", "^0.4.4"],
|
|
148
|
+
["react", "^19.2.7"],
|
|
149
|
+
["react-dom", "^19.2.7"],
|
|
150
|
+
["tailwind-merge", "^2.5.5"],
|
|
151
|
+
["tailwindcss-animate", "^1.0.7"],
|
|
152
|
+
];
|
|
153
|
+
// The base Radix packages the `site` preset's component files
|
|
154
|
+
// need to compile (label, separator, slot are imported by the
|
|
155
|
+
// vendored `button.tsx`, etc.). We seed the dependency block with
|
|
156
|
+
// them so the scaffolder never emits a project that's missing a
|
|
157
|
+
// Radix dep the components reference.
|
|
158
|
+
const baseRadixDependencies = [
|
|
159
|
+
["@radix-ui/react-label", "^2.1.0"],
|
|
160
|
+
["@radix-ui/react-separator", "^1.1.0"],
|
|
161
|
+
["@radix-ui/react-slot", "^1.2.0"],
|
|
162
|
+
];
|
|
163
|
+
const presetExtras = siteDependencyEntries(new Set([
|
|
164
|
+
// Anything in the base blocks is already covered — drop it
|
|
165
|
+
// from the preset's contribution to avoid emitting the same
|
|
166
|
+
// key twice in the JSON object.
|
|
167
|
+
...baseDependencies.map(([name]) => name),
|
|
168
|
+
...baseRadixDependencies.map(([name]) => name),
|
|
169
|
+
]));
|
|
170
|
+
// Merge into a single dedup'd map. Preset extras win on conflict
|
|
171
|
+
// (e.g. a future site preset may pin a newer Radix version than
|
|
172
|
+
// the base set), so they go in last.
|
|
173
|
+
const merged = new Map();
|
|
174
|
+
for (const [name, version] of baseDependencies)
|
|
175
|
+
merged.set(name, version);
|
|
176
|
+
for (const [name, version] of baseRadixDependencies) {
|
|
177
|
+
merged.set(name, version);
|
|
178
|
+
}
|
|
179
|
+
for (const dep of presetExtras)
|
|
180
|
+
merged.set(dep.name, dep.version);
|
|
181
|
+
// Render as a stable, alphabetised JSON object body. We keep
|
|
182
|
+
// the 4-space indent and the no-trailing-comma convention so the
|
|
183
|
+
// output is diff-friendly.
|
|
184
|
+
const lines = [];
|
|
185
|
+
const keys = [...merged.keys()].sort();
|
|
186
|
+
for (const name of keys) {
|
|
187
|
+
const version = merged.get(name);
|
|
188
|
+
lines.push(` "${name}": ${JSON.stringify(version)}`);
|
|
189
|
+
}
|
|
190
|
+
return lines.join(",\n");
|
|
191
|
+
}
|
|
192
|
+
function renderTemplate(input, tokens) {
|
|
193
|
+
return input.replace(/\{\{\s*([a-zA-Z][a-zA-Z0-9_]*)\s*\}\}/g, (full, key) => {
|
|
194
|
+
const value = tokens[key];
|
|
195
|
+
if (typeof value === "string") {
|
|
196
|
+
return value;
|
|
197
|
+
}
|
|
198
|
+
return full;
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
function templateUiComponentName(filePath) {
|
|
202
|
+
if (path.basename(path.dirname(filePath)) !== "ui")
|
|
203
|
+
return null;
|
|
204
|
+
const baseName = path.basename(filePath);
|
|
205
|
+
if (!baseName.endsWith(".tsx.tmpl"))
|
|
206
|
+
return null;
|
|
207
|
+
return baseName.slice(0, -".tsx.tmpl".length);
|
|
208
|
+
}
|
|
209
|
+
function shouldSkipTemplate(filePath, tokens) {
|
|
210
|
+
const component = templateUiComponentName(filePath);
|
|
211
|
+
return Boolean(component && !tokens.uiComponents.includes(component));
|
|
212
|
+
}
|
|
213
|
+
async function exists(p) {
|
|
214
|
+
try {
|
|
215
|
+
await fs.stat(p);
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
return false;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
async function ensureDir(p) {
|
|
223
|
+
await fs.mkdir(p, { recursive: true });
|
|
224
|
+
}
|
|
225
|
+
async function readPackageVersion() {
|
|
226
|
+
const packageJsonUrl = new URL("../package.json", import.meta.url);
|
|
227
|
+
const raw = await fs.readFile(packageJsonUrl, "utf8");
|
|
228
|
+
const parsed = JSON.parse(raw);
|
|
229
|
+
return parsed.version ?? "0.0.0";
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Default three-layer file ownership for a freshly scaffolded
|
|
233
|
+
* project.
|
|
234
|
+
*/
|
|
235
|
+
function buildDefaultManagedFiles(input) {
|
|
236
|
+
const userOwned = [
|
|
237
|
+
"app/page.tsx",
|
|
238
|
+
"components/site/site-header.tsx",
|
|
239
|
+
"components/site/site-footer.tsx",
|
|
240
|
+
"lib/content/models.ts",
|
|
241
|
+
];
|
|
242
|
+
if (input.contentSourceId === "blog") {
|
|
243
|
+
userOwned.push("app/blog/page.tsx", "app/blog/[slug]/page.tsx");
|
|
244
|
+
}
|
|
245
|
+
const bridgeOwned = ["worker/index.ts"];
|
|
246
|
+
// Feature-module files: bridge-owned for the entry point,
|
|
247
|
+
// user-owned for sub-components. Mirrors the ownership tags
|
|
248
|
+
// declared in `registry-items.ts`.
|
|
249
|
+
if (input.enableSiteSettings) {
|
|
250
|
+
bridgeOwned.push("lib/site/settings.ts");
|
|
251
|
+
}
|
|
252
|
+
if (input.enableBlocks) {
|
|
253
|
+
bridgeOwned.push("components/page-blocks.tsx");
|
|
254
|
+
userOwned.push("components/page-blocks/hero-block.tsx", "components/page-blocks/feature-grid-block.tsx", "components/page-blocks/story-block.tsx", "components/page-blocks/latest-posts-block.tsx");
|
|
255
|
+
}
|
|
256
|
+
if (input.enableAuth) {
|
|
257
|
+
bridgeOwned.push("lib/auth.config.ts", "app/api/auth/google/route.ts", "app/api/auth/google/callback/route.ts", "app/api/auth/verify-email/route.ts", "app/api/auth/viewer/route.ts", "migrations/0001_init.sql");
|
|
258
|
+
userOwned.push("app/login/page.tsx", "app/register/page.tsx");
|
|
259
|
+
}
|
|
260
|
+
if (input.enableAdmin) {
|
|
261
|
+
bridgeOwned.push("app/admin/layout.tsx", "app/admin/page.tsx", "app/admin/loading.tsx", "app/admin/account/page.tsx", "app/admin/content-models/page.tsx", "lib/admin/nav.ts", "lib/admin/actions.ts", "lib/admin/context.tsx", "migrations/0002_admin_seed.sql");
|
|
262
|
+
}
|
|
263
|
+
if (input.enablePages) {
|
|
264
|
+
bridgeOwned.push("lib/pages/model.ts", "lib/pages/source.ts", "app/[slug]/page.tsx");
|
|
265
|
+
}
|
|
266
|
+
if (input.enableSearch) {
|
|
267
|
+
bridgeOwned.push("lib/search/config.ts", "migrations/0003_search_index.sql");
|
|
268
|
+
userOwned.push("components/search/search-dialog.tsx");
|
|
269
|
+
}
|
|
270
|
+
return {
|
|
271
|
+
platform: [
|
|
272
|
+
"package.json",
|
|
273
|
+
"wrangler.jsonc",
|
|
274
|
+
"next.config.ts",
|
|
275
|
+
".dev.vars.example",
|
|
276
|
+
],
|
|
277
|
+
bridge: bridgeOwned,
|
|
278
|
+
user: userOwned,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
export async function resolveTemplatesDir() {
|
|
282
|
+
const compiled = path.resolve(import.meta.dirname, "templates");
|
|
283
|
+
const fromSource = path.resolve(import.meta.dirname, "..", "src", "templates");
|
|
284
|
+
return (await exists(compiled)) ? compiled : fromSource;
|
|
285
|
+
}
|
|
286
|
+
async function copyDir(src, dest) {
|
|
287
|
+
await ensureDir(dest);
|
|
288
|
+
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
289
|
+
for (const entry of entries) {
|
|
290
|
+
const from = path.join(src, entry.name);
|
|
291
|
+
const to = path.join(dest, entry.name);
|
|
292
|
+
if (entry.isDirectory()) {
|
|
293
|
+
await copyDir(from, to);
|
|
294
|
+
}
|
|
295
|
+
else if (entry.isFile()) {
|
|
296
|
+
await fs.copyFile(from, to);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Render the project. `templatesDir` is the absolute path to
|
|
302
|
+
* `src/templates/` inside the scaffolder package; `outDir` is the
|
|
303
|
+
* target directory the user picked in the prompt (relative or
|
|
304
|
+
* absolute). Existing directories are not removed — the caller is
|
|
305
|
+
* responsible for picking a clean target.
|
|
306
|
+
*/
|
|
307
|
+
export async function render(answers, templatesDir, outDir) {
|
|
308
|
+
const scaffoldVersion = await readPackageVersion();
|
|
309
|
+
const tokens = await buildTokenMap(answers, scaffoldVersion);
|
|
310
|
+
const absoluteOut = path.resolve(process.cwd(), outDir);
|
|
311
|
+
if (await exists(absoluteOut)) {
|
|
312
|
+
const entries = await fs.readdir(absoluteOut);
|
|
313
|
+
if (entries.length > 0) {
|
|
314
|
+
throw new Error(`Target directory ${absoluteOut} is not empty. Pick an empty path.`);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
await ensureDir(absoluteOut);
|
|
318
|
+
// Build the initial v2 registry manifest. This is the single
|
|
319
|
+
// source of truth for the project's state.
|
|
320
|
+
const managedFiles = buildDefaultManagedFiles({
|
|
321
|
+
contentSourceId: answers.contentSource.id,
|
|
322
|
+
enableSiteSettings: answers.enableSiteSettings,
|
|
323
|
+
enableBlocks: answers.enableBlocks,
|
|
324
|
+
enableAuth: answers.enableAuth,
|
|
325
|
+
enableAdmin: answers.enableAdmin,
|
|
326
|
+
enablePages: answers.enablePages,
|
|
327
|
+
enableSearch: answers.enableSearch,
|
|
328
|
+
});
|
|
329
|
+
const manifest = buildInitialRegistryManifest({
|
|
330
|
+
projectName: answers.projectName,
|
|
331
|
+
scaffoldVersion,
|
|
332
|
+
notionxCore: answers.notionxSource,
|
|
333
|
+
defaultLocale: answers.defaultLocale,
|
|
334
|
+
supportedLocales: answers.supportedLocales,
|
|
335
|
+
enableSiteSettings: answers.enableSiteSettings,
|
|
336
|
+
enableBlocks: answers.enableBlocks,
|
|
337
|
+
enableAuth: answers.enableAuth,
|
|
338
|
+
enableAdmin: answers.enableAdmin,
|
|
339
|
+
enablePages: answers.enablePages,
|
|
340
|
+
enableSearch: answers.enableSearch,
|
|
341
|
+
contentSource: {
|
|
342
|
+
id: answers.contentSource.id,
|
|
343
|
+
title: answers.contentSource.title,
|
|
344
|
+
fields: answers.contentSource.fields.map((f) => ({
|
|
345
|
+
key: f.key,
|
|
346
|
+
notionName: f.notionName,
|
|
347
|
+
})),
|
|
348
|
+
},
|
|
349
|
+
managedFiles,
|
|
350
|
+
});
|
|
351
|
+
await writeRegistryManifest(absoluteOut, manifest);
|
|
352
|
+
// Feature flags drive the fallback-template selection: when a
|
|
353
|
+
// flag is false, the Notion-backed version is skipped and the
|
|
354
|
+
// `.fallback.ts.tmpl` variant is rendered in its place (so the
|
|
355
|
+
// output filename is unchanged).
|
|
356
|
+
const featureFlags = {
|
|
357
|
+
siteSettings: answers.enableSiteSettings,
|
|
358
|
+
blocks: answers.enableBlocks,
|
|
359
|
+
auth: answers.enableAuth,
|
|
360
|
+
admin: answers.enableAdmin,
|
|
361
|
+
pages: answers.enablePages,
|
|
362
|
+
search: answers.enableSearch,
|
|
363
|
+
};
|
|
364
|
+
// Walk templates/ — every file is either a `.tmpl` (interpolated and
|
|
365
|
+
// written without the `.tmpl` suffix) or a literal copy.
|
|
366
|
+
const entries = await fs.readdir(templatesDir, { withFileTypes: true });
|
|
367
|
+
for (const entry of entries) {
|
|
368
|
+
const from = path.join(templatesDir, entry.name);
|
|
369
|
+
if (entry.isDirectory()) {
|
|
370
|
+
const dest = path.join(absoluteOut, entry.name);
|
|
371
|
+
await copyDirWithRender(from, dest, tokens, featureFlags);
|
|
372
|
+
}
|
|
373
|
+
else if (entry.isFile()) {
|
|
374
|
+
if (shouldSkipTemplate(from, tokens))
|
|
375
|
+
continue;
|
|
376
|
+
if (shouldSkipFeatureTemplate(from, featureFlags))
|
|
377
|
+
continue;
|
|
378
|
+
await writeFileWithRender(from, absoluteOut, tokens);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Feature-gated template skip rules. When a feature is disabled, the
|
|
384
|
+
* Notion-backed `.tmpl` is skipped so the `.fallback.ts.tmpl` variant
|
|
385
|
+
* (rendered to the same output filename) takes its place. The
|
|
386
|
+
* `page-blocks/` subdirectory is also skipped entirely when blocks
|
|
387
|
+
* are disabled — the fallback `page-blocks.tsx` is a no-op that
|
|
388
|
+
* doesn't need the sub-components.
|
|
389
|
+
*/
|
|
390
|
+
function shouldSkipFeatureTemplate(filePath, flags) {
|
|
391
|
+
const normalized = filePath.split(path.sep).join("/");
|
|
392
|
+
if (!flags.siteSettings && normalized.endsWith("lib/site/settings.ts.tmpl")) {
|
|
393
|
+
return true;
|
|
394
|
+
}
|
|
395
|
+
if (!flags.blocks && normalized.endsWith("components/page-blocks.tsx.tmpl")) {
|
|
396
|
+
return true;
|
|
397
|
+
}
|
|
398
|
+
// Skip the entire `components/page-blocks/` subdirectory contents
|
|
399
|
+
// when blocks are disabled. The fallback `page-blocks.tsx` doesn't
|
|
400
|
+
// import any of the sub-components.
|
|
401
|
+
if (!flags.blocks && normalized.includes("/components/page-blocks/")) {
|
|
402
|
+
return true;
|
|
403
|
+
}
|
|
404
|
+
// Auth: skip the Notion-backed auth config and auth API routes
|
|
405
|
+
// when auth is disabled. The fallback `auth.config.ts` is a no-op
|
|
406
|
+
// stub, and the auth route handlers are omitted entirely.
|
|
407
|
+
if (!flags.auth && normalized.endsWith("lib/auth.config.ts.tmpl")) {
|
|
408
|
+
return true;
|
|
409
|
+
}
|
|
410
|
+
if (!flags.auth && normalized.includes("/app/api/auth/")) {
|
|
411
|
+
return true;
|
|
412
|
+
}
|
|
413
|
+
if (!flags.auth && normalized.includes("/app/login/")) {
|
|
414
|
+
return true;
|
|
415
|
+
}
|
|
416
|
+
if (!flags.auth && normalized.includes("/app/register/")) {
|
|
417
|
+
return true;
|
|
418
|
+
}
|
|
419
|
+
// Skip the auth D1 migration (users/sessions/rate-limits tables)
|
|
420
|
+
// when auth is disabled.
|
|
421
|
+
if (!flags.auth && normalized.endsWith("migrations/0001_init.sql.tmpl")) {
|
|
422
|
+
return true;
|
|
423
|
+
}
|
|
424
|
+
// Admin: skip the entire admin tree when admin is disabled.
|
|
425
|
+
if (!flags.admin && normalized.includes("/app/admin/")) {
|
|
426
|
+
return true;
|
|
427
|
+
}
|
|
428
|
+
if (!flags.admin && normalized.includes("/lib/admin/")) {
|
|
429
|
+
return true;
|
|
430
|
+
}
|
|
431
|
+
// Skip the admin seed migration when admin is disabled.
|
|
432
|
+
if (!flags.admin && normalized.endsWith("migrations/0002_admin_seed.sql.tmpl")) {
|
|
433
|
+
return true;
|
|
434
|
+
}
|
|
435
|
+
// Pages: skip the pages lib and dynamic slug routes when pages
|
|
436
|
+
// is disabled. The fallback `app/page.tsx` renders a static home.
|
|
437
|
+
if (!flags.pages && normalized.includes("/lib/pages/")) {
|
|
438
|
+
return true;
|
|
439
|
+
}
|
|
440
|
+
if (!flags.pages && normalized.includes("/app/[slug]/")) {
|
|
441
|
+
return true;
|
|
442
|
+
}
|
|
443
|
+
if (!flags.pages && normalized.endsWith("app/page.tsx.tmpl")) {
|
|
444
|
+
return true;
|
|
445
|
+
}
|
|
446
|
+
// Search: skip the Notion-backed search config and the search
|
|
447
|
+
// index migration when search is disabled. The fallback
|
|
448
|
+
// `lib/search/config.ts` is a no-op stub exporting `undefined`.
|
|
449
|
+
if (!flags.search && normalized.endsWith("lib/search/config.ts.tmpl")) {
|
|
450
|
+
return true;
|
|
451
|
+
}
|
|
452
|
+
if (!flags.search && normalized.includes("/components/search/")) {
|
|
453
|
+
return true;
|
|
454
|
+
}
|
|
455
|
+
if (!flags.search && normalized.endsWith("migrations/0003_search_index.sql.tmpl")) {
|
|
456
|
+
return true;
|
|
457
|
+
}
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
460
|
+
async function copyDirWithRender(src, dest, tokens, featureFlags) {
|
|
461
|
+
await ensureDir(dest);
|
|
462
|
+
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
463
|
+
for (const entry of entries) {
|
|
464
|
+
const from = path.join(src, entry.name);
|
|
465
|
+
if (entry.isDirectory()) {
|
|
466
|
+
// Directory names may also contain tokens (e.g. the blog page
|
|
467
|
+
// lives at `app/{{contentSourceListPath}}/page.tsx.tmpl` so
|
|
468
|
+
// the directory itself must be rendered to `/blog` at scaffold
|
|
469
|
+
// time). Falling through to a literal name would produce an
|
|
470
|
+
// invalid `{{contentSourceListPath}}` folder in the project.
|
|
471
|
+
const renderedName = renderTemplate(entry.name, tokens);
|
|
472
|
+
await copyDirWithRender(from, path.join(dest, renderedName), tokens, featureFlags);
|
|
473
|
+
}
|
|
474
|
+
else if (entry.isFile()) {
|
|
475
|
+
// Per-preset component filter: the `components/ui/` tree in
|
|
476
|
+
// the templates directory carries the *union* of every preset
|
|
477
|
+
// (so we only have to maintain one copy of each shadcn
|
|
478
|
+
// component). At copy time, drop files that the active preset
|
|
479
|
+
// didn't opt into. Since 0.5.4 only the `site` preset
|
|
480
|
+
// survives, so this filter is equivalent to "copy all shadcn
|
|
481
|
+
// components" — kept here so a future preset addition can
|
|
482
|
+
// slot in without touching the renderer.
|
|
483
|
+
if (isUiDirectory(src) && !shouldCopyUiComponent(entry.name)) {
|
|
484
|
+
continue;
|
|
485
|
+
}
|
|
486
|
+
if (shouldSkipFeatureTemplate(from, featureFlags))
|
|
487
|
+
continue;
|
|
488
|
+
await writeFileWithRender(from, dest, tokens);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* True when `dir` is the `components/ui/` directory of the
|
|
494
|
+
* templates tree. Used to gate the per-preset component filter
|
|
495
|
+
* (see `copyDirWithRender`).
|
|
496
|
+
*/
|
|
497
|
+
function isUiDirectory(dir) {
|
|
498
|
+
const parts = dir.split(path.sep);
|
|
499
|
+
return (parts.length >= 2 &&
|
|
500
|
+
parts[parts.length - 1] === "ui" &&
|
|
501
|
+
parts[parts.length - 2] === "components");
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Decide whether a `components/ui/<file>.tsx.tmpl` should be
|
|
505
|
+
* copied for the given preset. The file list is the union across
|
|
506
|
+
* all presets, and the preset's `components` array declares which
|
|
507
|
+
* ones survive.
|
|
508
|
+
*
|
|
509
|
+
* Files that aren't `.tsx.tmpl` shadcn component copies (e.g. a
|
|
510
|
+
* future `index.ts` helper or a barrel) are always copied — only
|
|
511
|
+
* the named shadcn components participate in the filter.
|
|
512
|
+
*/
|
|
513
|
+
function shouldCopyUiComponent(fileName) {
|
|
514
|
+
if (!fileName.endsWith(".tsx.tmpl"))
|
|
515
|
+
return true;
|
|
516
|
+
const base = fileName.slice(0, -".tsx.tmpl".length);
|
|
517
|
+
const allowed = new Set(siteComponentNames());
|
|
518
|
+
return allowed.has(base);
|
|
519
|
+
}
|
|
520
|
+
async function writeFileWithRender(from, toDir, tokens) {
|
|
521
|
+
const baseName = path.basename(from);
|
|
522
|
+
// `.fallback.ts.tmpl` / `.fallback.tsx.tmpl` variants render to
|
|
523
|
+
// the same output filename as their Notion-backed counterpart
|
|
524
|
+
// (i.e. `settings.fallback.ts.tmpl` → `settings.ts`). The
|
|
525
|
+
// `.fallback.` segment is stripped in addition to `.tmpl`.
|
|
526
|
+
const isFallbackTmpl = baseName.includes(".fallback.");
|
|
527
|
+
const isTmpl = baseName.endsWith(".tmpl");
|
|
528
|
+
let outName;
|
|
529
|
+
if (isTmpl) {
|
|
530
|
+
outName = isFallbackTmpl
|
|
531
|
+
? baseName.replace(/\.fallback\.(ts|tsx)\.tmpl$/, ".$1")
|
|
532
|
+
: baseName.slice(0, -".tmpl".length);
|
|
533
|
+
}
|
|
534
|
+
else {
|
|
535
|
+
outName = baseName;
|
|
536
|
+
}
|
|
537
|
+
const outPath = path.join(toDir, outName);
|
|
538
|
+
if (isTmpl) {
|
|
539
|
+
const raw = await fs.readFile(from, "utf8");
|
|
540
|
+
const rendered = renderTemplate(raw, tokens);
|
|
541
|
+
await ensureDir(path.dirname(outPath));
|
|
542
|
+
await fs.writeFile(outPath, rendered, "utf8");
|
|
543
|
+
}
|
|
544
|
+
else {
|
|
545
|
+
await ensureDir(path.dirname(outPath));
|
|
546
|
+
await fs.copyFile(from, outPath);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
|