@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.
Files changed (239) hide show
  1. package/README.md +139 -0
  2. package/dist/answers.js +332 -0
  3. package/dist/answers.js.map +1 -0
  4. package/dist/cli-notionx.js +388 -0
  5. package/dist/cli-notionx.js.map +1 -0
  6. package/dist/cli-notionx.test.js +277 -0
  7. package/dist/cli-notionx.test.js.map +1 -0
  8. package/dist/diff.js +40 -0
  9. package/dist/diff.js.map +1 -0
  10. package/dist/diff.test.js +90 -0
  11. package/dist/diff.test.js.map +1 -0
  12. package/dist/index.js +99 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/locale-add/apply.js +39 -0
  15. package/dist/locale-add/apply.js.map +1 -0
  16. package/dist/locale-add/format.js +38 -0
  17. package/dist/locale-add/format.js.map +1 -0
  18. package/dist/locale-add/list.js +44 -0
  19. package/dist/locale-add/list.js.map +1 -0
  20. package/dist/locale-add/list.test.js +45 -0
  21. package/dist/locale-add/list.test.js.map +1 -0
  22. package/dist/locale-add/plan.js +128 -0
  23. package/dist/locale-add/plan.js.map +1 -0
  24. package/dist/locale-add/validate.js +46 -0
  25. package/dist/locale-add/validate.js.map +1 -0
  26. package/dist/metadata.js +41 -0
  27. package/dist/metadata.js.map +1 -0
  28. package/dist/notion-translation-sources/apply.js +61 -0
  29. package/dist/notion-translation-sources/apply.js.map +1 -0
  30. package/dist/notion-translation-sources/index.js +3 -0
  31. package/dist/notion-translation-sources/index.js.map +1 -0
  32. package/dist/notion-translation-sources/plan.js +33 -0
  33. package/dist/notion-translation-sources/plan.js.map +1 -0
  34. package/dist/notionx-source.js +142 -0
  35. package/dist/notionx-source.js.map +1 -0
  36. package/dist/notionx-source.test.js +144 -0
  37. package/dist/notionx-source.test.js.map +1 -0
  38. package/dist/password.js +18 -0
  39. package/dist/password.js.map +1 -0
  40. package/dist/presets.js +83 -0
  41. package/dist/presets.js.map +1 -0
  42. package/dist/presets.test.js +50 -0
  43. package/dist/presets.test.js.map +1 -0
  44. package/dist/prompt.js +218 -0
  45. package/dist/prompt.js.map +1 -0
  46. package/dist/provision/cloudflare.js +236 -0
  47. package/dist/provision/cloudflare.js.map +1 -0
  48. package/dist/provision/dependencies.js +219 -0
  49. package/dist/provision/dependencies.js.map +1 -0
  50. package/dist/provision/index.js +681 -0
  51. package/dist/provision/index.js.map +1 -0
  52. package/dist/provision/index.test.js +54 -0
  53. package/dist/provision/index.test.js.map +1 -0
  54. package/dist/provision/inspect.js +109 -0
  55. package/dist/provision/inspect.js.map +1 -0
  56. package/dist/provision/inspect.test.js +75 -0
  57. package/dist/provision/inspect.test.js.map +1 -0
  58. package/dist/provision/notion.js +1981 -0
  59. package/dist/provision/notion.js.map +1 -0
  60. package/dist/provision/notion.test.js +542 -0
  61. package/dist/provision/notion.test.js.map +1 -0
  62. package/dist/provision/ntn-credentials.js +198 -0
  63. package/dist/provision/ntn-credentials.js.map +1 -0
  64. package/dist/provision/options.js +15 -0
  65. package/dist/provision/options.js.map +1 -0
  66. package/dist/provision/password-hash.js +78 -0
  67. package/dist/provision/password-hash.js.map +1 -0
  68. package/dist/provision/prompts.js +115 -0
  69. package/dist/provision/prompts.js.map +1 -0
  70. package/dist/provision/repair.js +48 -0
  71. package/dist/provision/repair.js.map +1 -0
  72. package/dist/provision/repair.test.js +141 -0
  73. package/dist/provision/repair.test.js.map +1 -0
  74. package/dist/provision/shell.js +84 -0
  75. package/dist/provision/shell.js.map +1 -0
  76. package/dist/provision/wire.js +78 -0
  77. package/dist/provision/wire.js.map +1 -0
  78. package/dist/registry/doctor.js +181 -0
  79. package/dist/registry/doctor.js.map +1 -0
  80. package/dist/registry/doctor.test.js +180 -0
  81. package/dist/registry/doctor.test.js.map +1 -0
  82. package/dist/registry/install.js +217 -0
  83. package/dist/registry/install.js.map +1 -0
  84. package/dist/registry/install.test.js +168 -0
  85. package/dist/registry/install.test.js.map +1 -0
  86. package/dist/registry/load-registry.js +24 -0
  87. package/dist/registry/load-registry.js.map +1 -0
  88. package/dist/registry/load-registry.test.js +59 -0
  89. package/dist/registry/load-registry.test.js.map +1 -0
  90. package/dist/registry/migration-planner.js +204 -0
  91. package/dist/registry/migration-planner.js.map +1 -0
  92. package/dist/registry/migration-planner.test.js +340 -0
  93. package/dist/registry/migration-planner.test.js.map +1 -0
  94. package/dist/registry/migrations-store.js +125 -0
  95. package/dist/registry/migrations-store.js.map +1 -0
  96. package/dist/registry/migrations-store.test.js +163 -0
  97. package/dist/registry/migrations-store.test.js.map +1 -0
  98. package/dist/registry/migrations-types.js +25 -0
  99. package/dist/registry/migrations-types.js.map +1 -0
  100. package/dist/registry/project-meta.js +84 -0
  101. package/dist/registry/project-meta.js.map +1 -0
  102. package/dist/registry/registry-items.js +354 -0
  103. package/dist/registry/registry-items.js.map +1 -0
  104. package/dist/registry/registry-items.test.js +99 -0
  105. package/dist/registry/registry-items.test.js.map +1 -0
  106. package/dist/registry/registry-store.js +232 -0
  107. package/dist/registry/registry-store.js.map +1 -0
  108. package/dist/registry/registry-store.test.js +136 -0
  109. package/dist/registry/registry-store.test.js.map +1 -0
  110. package/dist/registry/registry-types.js +18 -0
  111. package/dist/registry/registry-types.js.map +1 -0
  112. package/dist/registry/registry-types.test.js +146 -0
  113. package/dist/registry/registry-types.test.js.map +1 -0
  114. package/dist/registry/render-content-source-files.js +158 -0
  115. package/dist/registry/render-content-source-files.js.map +1 -0
  116. package/dist/registry/render-multi-source.js +296 -0
  117. package/dist/registry/render-multi-source.js.map +1 -0
  118. package/dist/registry/render-multi-source.test.js +110 -0
  119. package/dist/registry/render-multi-source.test.js.map +1 -0
  120. package/dist/registry/text-utils.js +42 -0
  121. package/dist/registry/text-utils.js.map +1 -0
  122. package/dist/registry/uninstall.js +250 -0
  123. package/dist/registry/uninstall.js.map +1 -0
  124. package/dist/registry/uninstall.test.js +264 -0
  125. package/dist/registry/uninstall.test.js.map +1 -0
  126. package/dist/registry/update.js +280 -0
  127. package/dist/registry/update.js.map +1 -0
  128. package/dist/registry/update.test.js +229 -0
  129. package/dist/registry/update.test.js.map +1 -0
  130. package/dist/render.js +549 -0
  131. package/dist/render.js.map +1 -0
  132. package/dist/render.test.js +414 -0
  133. package/dist/render.test.js.map +1 -0
  134. package/dist/templates/.dev.vars.example.tmpl +32 -0
  135. package/dist/templates/.gitignore.tmpl +58 -0
  136. package/dist/templates/README.md.tmpl +417 -0
  137. package/dist/templates/app/[slug]/page.tsx.tmpl +55 -0
  138. package/dist/templates/app/admin/account/page.tsx.tmpl +18 -0
  139. package/dist/templates/app/admin/content-models/page.tsx.tmpl +6 -0
  140. package/dist/templates/app/admin/layout.tsx.tmpl +90 -0
  141. package/dist/templates/app/admin/loading.tsx.tmpl +6 -0
  142. package/dist/templates/app/admin/page.tsx.tmpl +17 -0
  143. package/dist/templates/app/api/auth/google/callback/route.ts.tmpl +3 -0
  144. package/dist/templates/app/api/auth/google/route.ts.tmpl +3 -0
  145. package/dist/templates/app/api/auth/verify-email/route.ts.tmpl +3 -0
  146. package/dist/templates/app/api/auth/viewer/route.ts.tmpl +3 -0
  147. package/dist/templates/app/api/health/route.ts.tmpl +3 -0
  148. package/dist/templates/app/api/{{contentSourceId}}/[slug]/route.ts.tmpl +27 -0
  149. package/dist/templates/app/api/{{contentSourceId}}/route.ts.tmpl +18 -0
  150. package/dist/templates/app/globals.css.tmpl +109 -0
  151. package/dist/templates/app/layout.tsx.tmpl +56 -0
  152. package/dist/templates/app/login/page.tsx.tmpl +154 -0
  153. package/dist/templates/app/page.fallback.tsx.tmpl +31 -0
  154. package/dist/templates/app/page.tsx.tmpl +42 -0
  155. package/dist/templates/app/register/page.tsx.tmpl +138 -0
  156. package/dist/templates/app/{{contentSourceListPath}}/[slug]/page.tsx.tmpl +113 -0
  157. package/dist/templates/app/{{contentSourceListPath}}/page.tsx.tmpl +74 -0
  158. package/dist/templates/components/content/post-card.tsx.tmpl +80 -0
  159. package/dist/templates/components/notion-blocks.tsx.tmpl +668 -0
  160. package/dist/templates/components/page-blocks/feature-grid-block.tsx.tmpl +68 -0
  161. package/dist/templates/components/page-blocks/hero-block.tsx.tmpl +73 -0
  162. package/dist/templates/components/page-blocks/latest-posts-block.tsx.tmpl +59 -0
  163. package/dist/templates/components/page-blocks/story-block.tsx.tmpl +70 -0
  164. package/dist/templates/components/page-blocks.fallback.tsx.tmpl +17 -0
  165. package/dist/templates/components/page-blocks.tsx.tmpl +32 -0
  166. package/dist/templates/components/search/search-dialog.tsx.tmpl +171 -0
  167. package/dist/templates/components/site/locale-switcher.tsx.tmpl +65 -0
  168. package/dist/templates/components/site/site-footer.tsx.tmpl +106 -0
  169. package/dist/templates/components/site/site-header.tsx.tmpl +80 -0
  170. package/dist/templates/components/site/site-shell.tsx.tmpl +20 -0
  171. package/dist/templates/components/site/theme-bootstrap.tsx.tmpl +51 -0
  172. package/dist/templates/components/theme-provider.tsx.tmpl +14 -0
  173. package/dist/templates/components/theme-toggle.tsx.tmpl +38 -0
  174. package/dist/templates/components/ui/accordion.tsx.tmpl +56 -0
  175. package/dist/templates/components/ui/alert.tsx.tmpl +59 -0
  176. package/dist/templates/components/ui/aspect-ratio.tsx.tmpl +8 -0
  177. package/dist/templates/components/ui/avatar.tsx.tmpl +44 -0
  178. package/dist/templates/components/ui/badge.tsx.tmpl +33 -0
  179. package/dist/templates/components/ui/button.tsx.tmpl +56 -0
  180. package/dist/templates/components/ui/card.tsx.tmpl +61 -0
  181. package/dist/templates/components/ui/checkbox.tsx.tmpl +28 -0
  182. package/dist/templates/components/ui/dialog.tsx.tmpl +104 -0
  183. package/dist/templates/components/ui/dropdown-menu.tsx.tmpl +183 -0
  184. package/dist/templates/components/ui/input.tsx.tmpl +21 -0
  185. package/dist/templates/components/ui/label.tsx.tmpl +25 -0
  186. package/dist/templates/components/ui/popover.tsx.tmpl +30 -0
  187. package/dist/templates/components/ui/radio-group.tsx.tmpl +44 -0
  188. package/dist/templates/components/ui/select.tsx.tmpl +150 -0
  189. package/dist/templates/components/ui/separator.tsx.tmpl +30 -0
  190. package/dist/templates/components/ui/sheet.tsx.tmpl +125 -0
  191. package/dist/templates/components/ui/skeleton.tsx.tmpl +15 -0
  192. package/dist/templates/components/ui/sonner.tsx.tmpl +30 -0
  193. package/dist/templates/components/ui/switch.tsx.tmpl +29 -0
  194. package/dist/templates/components/ui/table.tsx.tmpl +107 -0
  195. package/dist/templates/components/ui/tabs.tsx.tmpl +55 -0
  196. package/dist/templates/components/ui/textarea.tsx.tmpl +24 -0
  197. package/dist/templates/components/ui/tooltip.tsx.tmpl +30 -0
  198. package/dist/templates/components.json.tmpl +21 -0
  199. package/dist/templates/env.d.ts.tmpl +32 -0
  200. package/dist/templates/lib/admin/actions.ts.tmpl +43 -0
  201. package/dist/templates/lib/admin/context.tsx.tmpl +209 -0
  202. package/dist/templates/lib/admin/nav.ts.tmpl +23 -0
  203. package/dist/templates/lib/auth.config.fallback.ts.tmpl +10 -0
  204. package/dist/templates/lib/auth.config.ts.tmpl +45 -0
  205. package/dist/templates/lib/blocks/translations.ts.tmpl +44 -0
  206. package/dist/templates/lib/blog/translations.ts.tmpl +52 -0
  207. package/dist/templates/lib/content/models.ts.tmpl +53 -0
  208. package/dist/templates/lib/i18n/config.ts.tmpl +18 -0
  209. package/dist/templates/lib/i18n/index.ts.tmpl +1 -0
  210. package/dist/templates/lib/locale-contract/built-in.ts.tmpl +19 -0
  211. package/dist/templates/lib/locale-contract/index.ts.tmpl +3 -0
  212. package/dist/templates/lib/locale-contract/paths.ts.tmpl +29 -0
  213. package/dist/templates/lib/pages/model.ts.tmpl +16 -0
  214. package/dist/templates/lib/pages/source.ts.tmpl +566 -0
  215. package/dist/templates/lib/pages/translations.ts.tmpl +34 -0
  216. package/dist/templates/lib/search/config.fallback.ts.tmpl +11 -0
  217. package/dist/templates/lib/search/config.ts.tmpl +25 -0
  218. package/dist/templates/lib/site/config.ts.tmpl +120 -0
  219. package/dist/templates/lib/site/request-env.ts.tmpl +71 -0
  220. package/dist/templates/lib/site/settings.fallback.ts.tmpl +21 -0
  221. package/dist/templates/lib/site/settings.ts.tmpl +320 -0
  222. package/dist/templates/lib/site/translations.ts.tmpl +30 -0
  223. package/dist/templates/lib/utils.ts.tmpl +9 -0
  224. package/dist/templates/migrations/0001_init.sql.tmpl +57 -0
  225. package/dist/templates/migrations/0002_admin_seed.sql.tmpl +30 -0
  226. package/dist/templates/migrations/0003_search_index.sql.tmpl +29 -0
  227. package/dist/templates/next.config.ts.tmpl +18 -0
  228. package/dist/templates/package.json.tmpl +40 -0
  229. package/dist/templates/shims/cloudflare-workers-empty.mjs +4 -0
  230. package/dist/templates/shims/next-headers-empty.mjs +4 -0
  231. package/dist/templates/tests/smoke.test.ts.tmpl +83 -0
  232. package/dist/templates/tsconfig.json.tmpl +31 -0
  233. package/dist/templates/vite.config.ts.tmpl +53 -0
  234. package/dist/templates/vitest.config.ts.tmpl +13 -0
  235. package/dist/templates/worker/index.ts.tmpl +52 -0
  236. package/dist/templates/wrangler.jsonc.tmpl +44 -0
  237. package/dist/ui-presets.js +60 -0
  238. package/dist/ui-presets.js.map +1 -0
  239. package/package.json +60 -0
@@ -0,0 +1,52 @@
1
+ // Locale-aware blog lookup. Falls back to the default-locale
2
+ // translation when a target locale is missing (rule: hide).
3
+
4
+ import {
5
+ pickTranslation,
6
+ hideWhenMissing,
7
+ mapNotionPageToLocalizedContentTranslation,
8
+ } from "@notionx/core";
9
+ import { i18n } from "@/lib/i18n";
10
+ import { blogContract } from "@/lib/locale-contract";
11
+ import type { NotionPageLike } from "@notionx/core";
12
+
13
+ export type BlogTranslationExtra = {
14
+ summary: string;
15
+ tags: string[];
16
+ };
17
+
18
+ export type BlogTranslation = NonNullable<
19
+ ReturnType<typeof mapNotionPageToLocalizedContentTranslation<BlogTranslationExtra>>
20
+ >;
21
+
22
+ export function mapBlogTranslation(page: NotionPageLike): BlogTranslation | null {
23
+ return mapNotionPageToLocalizedContentTranslation<BlogTranslationExtra>(page, {
24
+ fields: {
25
+ title: "Title",
26
+ source: "Source",
27
+ locale: "Locale",
28
+ slug: "Slug",
29
+ published: "Published",
30
+ },
31
+ extraFields: {
32
+ summary: "Description",
33
+ tags: { field: "Tags", kind: "tags" },
34
+ },
35
+ isValidLocale: (locale) =>
36
+ (i18n.supportedLocales as readonly string[]).includes(locale),
37
+ });
38
+ }
39
+
40
+ export function pickBlogTranslation(
41
+ rows: readonly BlogTranslation[],
42
+ locale: string
43
+ ) {
44
+ return pickTranslation(rows, locale, blogContract, i18n.defaultLocale);
45
+ }
46
+
47
+ export function blogListForLocale(
48
+ rows: readonly BlogTranslation[],
49
+ locale: string
50
+ ) {
51
+ return hideWhenMissing(rows, locale);
52
+ }
@@ -0,0 +1,53 @@
1
+ // Notion-backed content sources registered with the notionx
2
+ // registry. To add another content source, run `notionx add <id>`
3
+ // (or paste a new `defineContentSource({...})` block by hand and
4
+ // append the variable to `contentSources` / `managedContentSources`).
5
+ //
6
+ // `siteSettingsSource` and `blocksSource` are *singleton* internal
7
+ // sources that back `lib/site/settings.ts` and `components/page-blocks`
8
+ // respectively. They are conditionally included based on the
9
+ // `enableSiteSettings` / `enableBlocks` flags. They live in their
10
+ // own `NOTION_*_DATA_SOURCE_ID` env vars so they can be shared
11
+ // across content sources and edited without redeploying. They're
12
+ // intentionally NOT in `contentSources` because they have no
13
+ // public list/detail pages — only the home page, SEO metadata, and
14
+ // page-blocks consume them. Operators can still see them in
15
+ // `/admin/content-models` (they're in the package registry), and
16
+ // can revalidate their KV cache from there.
17
+
18
+ import {
19
+ defineContentSource,
20
+ type ContentSource,
21
+ } from "@notionx/core/content";
22
+
23
+ // BEGIN generated-content-sources
24
+ // (Regenerated by `notionx add` / `notionx remove` / `notionx
25
+ // update`. Do not edit between these markers — the next update
26
+ // run will overwrite this block. To add a source by hand, use
27
+ // `notionx add <id>`.)
28
+ {{contentSourceDeclarations}}
29
+ // END generated-content-sources
30
+
31
+ // BEGIN generated-internal-sources
32
+ // (Regenerated by `notionx add` / `notionx remove` / `notionx
33
+ // update`. Do not edit between these markers.)
34
+ {{internalSourceDeclarations}}
35
+ // END generated-internal-sources
36
+
37
+ // `contentSources` is the public list shown in admin nav and
38
+ // iterated by search/revalidation. `managedContentSources`
39
+ // additionally includes any internal singleton sources
40
+ // (`blocksSource`, `siteSettingsSource`) so the worker registers
41
+ // them with `@notionx/core`'s `createNotionxWorker({ sources })`.
42
+ //
43
+ // `{{contentSourceSourcesVarNames}}` is a comma-joined list of
44
+ // `*Source` variable names for every installed content source.
45
+ // `{{internalSourceVarNames}}` is the same for internal sources.
46
+ export const contentSources = [
47
+ {{contentSourceSourcesVarNames}},
48
+ ] as const;
49
+ export const managedContentSources = [
50
+ {{contentSourceSourcesVarNames}},
51
+ {{internalSourceVarNames}},
52
+ ] as const;
53
+ export type ContentSourceId = (typeof contentSources)[number]["id"];
@@ -0,0 +1,18 @@
1
+ // Project-level i18n config. Re-exports the runtime helpers from
2
+ // `@notionx/core` so app code, route handlers, and components share
3
+ // one set of locale constants. The supported locales are baked in
4
+ // at scaffold time; use `npx notionx locale add <locale>` to extend
5
+ // an existing project.
6
+
7
+ import { defineI18nConfig } from "@notionx/core/i18n";
8
+
9
+ export const i18n = defineI18nConfig({
10
+ defaultLocale: "{{defaultLocale}}",
11
+ supportedLocales: {{supportedLocalesJson}},
12
+ });
13
+
14
+ export type AppLocale = (typeof i18n.supportedLocales)[number];
15
+
16
+ export function isAppLocale(value: string): value is AppLocale {
17
+ return (i18n.supportedLocales as readonly string[]).includes(value);
18
+ }
@@ -0,0 +1 @@
1
+ export * from "./config";
@@ -0,0 +1,19 @@
1
+ // Built-in locale contracts re-exported under a project-friendly
2
+ // import path. The list paths here are the canonical ones for the
3
+ // starter: the blog content source list and the page detail route.
4
+
5
+ import {
6
+ blogContract as coreBlogContract,
7
+ pagesContract as corePagesContract,
8
+ blocksContract as coreBlocksContract,
9
+ siteSettingsContract as coreSiteSettingsContract,
10
+ } from "@notionx/core";
11
+
12
+ export const blogContract = {
13
+ ...coreBlogContract,
14
+ listPath: "{{contentSourceListPath}}",
15
+ };
16
+
17
+ export const pagesContract = corePagesContract;
18
+ export const blocksContract = coreBlocksContract;
19
+ export const siteSettingsContract = coreSiteSettingsContract;
@@ -0,0 +1,3 @@
1
+ export * from "./built-in";
2
+ export * from "./paths";
3
+ export { defineLocaleContract } from "@notionx/core";
@@ -0,0 +1,29 @@
1
+ // Thin wrappers around the core path helpers that bake the project's
2
+ // default locale and the blog content source list path in. Route code
3
+ // should import from this module rather than the core helpers directly
4
+ // so the defaults stay consistent.
5
+
6
+ import { i18n } from "@/lib/i18n";
7
+ import {
8
+ localizedListPath as coreLocalizedListPath,
9
+ localizedDetailPathFor as coreLocalizedDetailPathFor,
10
+ stripLocalePrefix as coreStripLocalePrefix,
11
+ } from "@notionx/core";
12
+ import { blogContract } from "./built-in";
13
+
14
+ export function blogListPath(locale: string) {
15
+ return coreLocalizedListPath(locale, blogContract, i18n.defaultLocale);
16
+ }
17
+
18
+ export function blogDetailPath(locale: string, slug: string) {
19
+ return coreLocalizedDetailPathFor(
20
+ locale,
21
+ slug,
22
+ blogContract,
23
+ i18n.defaultLocale
24
+ );
25
+ }
26
+
27
+ export function stripBlogLocale(path: string, locale: string) {
28
+ return coreStripLocalePrefix(path, locale);
29
+ }
@@ -0,0 +1,16 @@
1
+ // Notion-backed site pages. Pages are different from article-like
2
+ // content sources: they define the site's information architecture,
3
+ // navigation/footer visibility, route slugs, SEO copy, and editable
4
+ // body blocks for pages such as home, about, blog, and privacy.
5
+
6
+ import {
7
+ defaultPagesDataSourceEnv,
8
+ defaultSitePageFields,
9
+ } from "@notionx/core/pages";
10
+
11
+ export const pageFields = {
12
+ ...defaultSitePageFields,
13
+ blocks: "Blocks",
14
+ } as const;
15
+
16
+ export const pagesDataSourceEnv = defaultPagesDataSourceEnv;