@ampless/admin 0.2.0-alpha.2 → 0.2.0-alpha.20

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 (49) hide show
  1. package/README.ja.md +73 -0
  2. package/README.md +3 -0
  3. package/dist/api/index.d.ts +1 -1
  4. package/dist/chunk-2ITWLRYF.js +38 -0
  5. package/dist/chunk-5JKOPRCO.js +41 -0
  6. package/dist/chunk-5Q6KVRZ2.js +250 -0
  7. package/dist/chunk-7IR4F7GA.js +6 -0
  8. package/dist/chunk-A3SWBQA6.js +71 -0
  9. package/dist/chunk-BC4B6DLO.js +21 -0
  10. package/dist/chunk-CQY55RDG.js +48 -0
  11. package/dist/chunk-CVJCMTYB.js +1197 -0
  12. package/dist/chunk-IM5MVZOH.js +1260 -0
  13. package/dist/chunk-JOASK4AM.js +360 -0
  14. package/dist/{chunk-TJR3ALRJ.js → chunk-OSUTPPAU.js} +171 -68
  15. package/dist/chunk-QXJIIBUQ.js +21 -0
  16. package/dist/chunk-S66L5CDS.js +335 -0
  17. package/dist/chunk-SRNH2IVA.js +149 -0
  18. package/dist/chunk-TZWSXAHD.js +32 -0
  19. package/dist/chunk-VXEVLHGL.js +10 -0
  20. package/dist/chunk-W6BXESPW.js +198 -0
  21. package/dist/chunk-XY4JWSMS.js +33 -0
  22. package/dist/components/admin-dashboard.d.ts +10 -0
  23. package/dist/components/admin-dashboard.js +9 -0
  24. package/dist/components/edit-post-view.d.ts +9 -0
  25. package/dist/components/edit-post-view.js +14 -0
  26. package/dist/components/index.d.ts +40 -21
  27. package/dist/components/index.js +32 -15
  28. package/dist/components/login-view.d.ts +5 -0
  29. package/dist/components/login-view.js +9 -0
  30. package/dist/components/mcp-tokens-view.d.ts +22 -0
  31. package/dist/components/mcp-tokens-view.js +9 -0
  32. package/dist/components/media-view.d.ts +5 -0
  33. package/dist/components/media-view.js +12 -0
  34. package/dist/components/new-post-view.d.ts +5 -0
  35. package/dist/components/new-post-view.js +14 -0
  36. package/dist/components/posts-list-view.d.ts +5 -0
  37. package/dist/components/posts-list-view.js +11 -0
  38. package/dist/components/users-list-view.d.ts +7 -0
  39. package/dist/components/users-list-view.js +9 -0
  40. package/dist/{i18n-ByHM_Bho.d.ts → i18n-MWvAMHzn.d.ts} +253 -2
  41. package/dist/index.d.ts +14 -9
  42. package/dist/index.js +18 -10
  43. package/dist/lib/theme-actions.d.ts +17 -0
  44. package/dist/lib/theme-actions.js +7 -0
  45. package/dist/metafile-esm.json +1 -1
  46. package/dist/pages/index.d.ts +67 -15
  47. package/dist/pages/index.js +147 -659
  48. package/package.json +12 -9
  49. package/dist/chunk-T2RSMFOI.js +0 -2074
@@ -32,9 +32,13 @@ var sidebar = {
32
32
  posts: "Posts",
33
33
  media: "Media",
34
34
  sites: "Sites",
35
+ users: "Users",
36
+ mcpTokens: "MCP tokens",
35
37
  viewSite: "View site",
36
38
  signOut: "Sign out",
37
- site: "Site"
39
+ site: "Site",
40
+ openMenu: "Open menu",
41
+ closeMenu: "Close menu"
38
42
  };
39
43
  var dashboard = {
40
44
  title: "Dashboard",
@@ -74,6 +78,20 @@ var posts = {
74
78
  tagsPlaceholder: "comma, separated, tags",
75
79
  tagsHint: "Used to group posts on tag pages (e.g. /tag/tech).",
76
80
  status: "Status",
81
+ noLayout: "No layout",
82
+ noLayoutHint: "Serve this post as bare HTML — no theme header, footer, or root layout. The body is returned as the entire response. Best paired with format: HTML when the body contains a full <!DOCTYPE html>…</html> document.",
83
+ formatStaticLabel: "Static (zip / file bundle)",
84
+ "static": {
85
+ pick: "Pick a .zip or one or more files",
86
+ pickHint: "Bundle assets must reference each other with relative paths only (no leading /). The zip's contents are extracted into a directory under your post slug and served verbatim — no theme chrome.",
87
+ currentBundle: "Current bundle: {count} files (entry: {entrypoint})",
88
+ pendingBundle: "Pending upload: {count} files, {size}",
89
+ issuesTitle: "{count} validation issue(s)",
90
+ issuesHint: "Fix the listed paths and re-upload. Absolute (/foo) and protocol-relative (//cdn.example/foo) references break under the bundle's URL prefix.",
91
+ emptyBundle: "No usable files found in the selection.",
92
+ noBundle: "Pick a bundle before saving.",
93
+ previewHint: "Static bundles render as the served HTML at /<slug>/. Preview by saving and visiting the public URL."
94
+ },
77
95
  saveChanges: "Save changes",
78
96
  createPost: "Create post",
79
97
  "delete": "Delete",
@@ -145,6 +163,25 @@ var sites = {
145
163
  label: "Site"
146
164
  }
147
165
  };
166
+ var users = {
167
+ list: {
168
+ title: "Users",
169
+ description: "Promote signed-up users to admin or editor. Sign-ups always start with no role and must be granted access here.",
170
+ columnEmail: "Email",
171
+ columnRole: "Role",
172
+ columnActions: "Actions",
173
+ save: "Save",
174
+ saving: "Saving...",
175
+ saved: "Saved.",
176
+ cannotEditSelf: "You cannot change your own role.",
177
+ empty: "No users yet.",
178
+ loading: "Loading users...",
179
+ error: "Failed to load users",
180
+ roleAdmin: "Admin",
181
+ roleEditor: "Editor",
182
+ roleNone: "None"
183
+ }
184
+ };
148
185
  var theme = {
149
186
  title: "Theme",
150
187
  activeLabel: "Active theme",
@@ -162,7 +199,14 @@ var theme = {
162
199
  customizationHeading: "{theme} customization",
163
200
  customizationHint: "Empty input resets to the manifest default.",
164
201
  lengthHelp: "CSS length, e.g. 0.5rem, 4px.",
165
- imagePlaceholder: "https://… or /media/…"
202
+ imagePlaceholder: "https://… or /media/…",
203
+ colorScheme: {
204
+ label: "Color scheme",
205
+ hint: "How the public site picks between the theme's light and dark token palettes.",
206
+ auto: "Auto (follow visitor's system)",
207
+ light: "Light only",
208
+ dark: "Dark only"
209
+ }
166
210
  };
167
211
  var editor = {
168
212
  linkPrompt: "URL",
@@ -223,6 +267,45 @@ var auth = {
223
267
  userExists: "An account with this email already exists."
224
268
  }
225
269
  };
270
+ var mcpTokens = {
271
+ title: "MCP tokens",
272
+ description: "Access tokens for the HTTP MCP endpoint. Use them in Claude Desktop / Cursor / any MCP-aware client to read and write this CMS over the wire.",
273
+ endpointTitle: "MCP endpoint",
274
+ endpointCopy: "Copy",
275
+ endpointCopied: "Copied",
276
+ endpointMissing: "Not deployed yet. Run `npm run sandbox` or push to Amplify Hosting to provision the endpoint URL.",
277
+ inertBanner: "Heads up: the endpoint validates tokens, but tool dispatch (list_posts / create_post / etc.) lands in v0.2 Phase 4. Valid tokens currently get a stub 200 response.",
278
+ createButton: "Create token",
279
+ createModalTitle: "Create token",
280
+ scopeLabel: "Scope",
281
+ scopeAll: "All sites",
282
+ expirationLabel: "Expiration",
283
+ expirationNever: "Never",
284
+ expiration30days: "30 days",
285
+ expiration90days: "90 days",
286
+ expirationCustom: "Custom date",
287
+ issueButton: "Issue token",
288
+ issuing: "Issuing...",
289
+ revealTitle: "Token issued",
290
+ revealHint: "This is the only time you will see this token. Copy it now — closing this dialog discards it permanently.",
291
+ copy: "Copy",
292
+ copied: "Copied!",
293
+ done: "Done",
294
+ loading: "Loading tokens...",
295
+ error: "Failed to load tokens",
296
+ listEmpty: "No tokens yet. Click 'Create token' to issue your first one.",
297
+ columnPrefix: "Prefix",
298
+ columnScope: "Scope",
299
+ columnCreated: "Created",
300
+ columnLastUsed: "Last used",
301
+ columnStatus: "Status",
302
+ lastUsedNever: "Never used",
303
+ statusActive: "Active",
304
+ statusRevoked: "Revoked",
305
+ statusExpired: "Expired",
306
+ revoke: "Revoke",
307
+ revokeConfirm: "Revoke this token? This cannot be undone."
308
+ };
226
309
  var en = {
227
310
  common: common,
228
311
  sidebar: sidebar,
@@ -231,9 +314,11 @@ var en = {
231
314
  media: media,
232
315
  mediaPicker: mediaPicker,
233
316
  sites: sites,
317
+ users: users,
234
318
  theme: theme,
235
319
  editor: editor,
236
320
  auth: auth,
321
+ mcpTokens: mcpTokens,
237
322
  "public": {
238
323
  back: "← Back",
239
324
  home: "← Home",
@@ -278,9 +363,13 @@ declare const dictionaries: {
278
363
  posts: string;
279
364
  media: string;
280
365
  sites: string;
366
+ users: string;
367
+ mcpTokens: string;
281
368
  viewSite: string;
282
369
  signOut: string;
283
370
  site: string;
371
+ openMenu: string;
372
+ closeMenu: string;
284
373
  };
285
374
  dashboard: {
286
375
  title: string;
@@ -320,6 +409,20 @@ declare const dictionaries: {
320
409
  tagsPlaceholder: string;
321
410
  tagsHint: string;
322
411
  status: string;
412
+ noLayout: string;
413
+ noLayoutHint: string;
414
+ formatStaticLabel: string;
415
+ static: {
416
+ pick: string;
417
+ pickHint: string;
418
+ currentBundle: string;
419
+ pendingBundle: string;
420
+ issuesTitle: string;
421
+ issuesHint: string;
422
+ emptyBundle: string;
423
+ noBundle: string;
424
+ previewHint: string;
425
+ };
323
426
  saveChanges: string;
324
427
  createPost: string;
325
428
  delete: string;
@@ -391,6 +494,25 @@ declare const dictionaries: {
391
494
  label: string;
392
495
  };
393
496
  };
497
+ users: {
498
+ list: {
499
+ title: string;
500
+ description: string;
501
+ columnEmail: string;
502
+ columnRole: string;
503
+ columnActions: string;
504
+ save: string;
505
+ saving: string;
506
+ saved: string;
507
+ cannotEditSelf: string;
508
+ empty: string;
509
+ loading: string;
510
+ error: string;
511
+ roleAdmin: string;
512
+ roleEditor: string;
513
+ roleNone: string;
514
+ };
515
+ };
394
516
  theme: {
395
517
  title: string;
396
518
  activeLabel: string;
@@ -409,6 +531,13 @@ declare const dictionaries: {
409
531
  customizationHint: string;
410
532
  lengthHelp: string;
411
533
  imagePlaceholder: string;
534
+ colorScheme: {
535
+ label: string;
536
+ hint: string;
537
+ auto: string;
538
+ light: string;
539
+ dark: string;
540
+ };
412
541
  };
413
542
  editor: {
414
543
  linkPrompt: string;
@@ -469,6 +598,45 @@ declare const dictionaries: {
469
598
  userExists: string;
470
599
  };
471
600
  };
601
+ mcpTokens: {
602
+ title: string;
603
+ description: string;
604
+ endpointTitle: string;
605
+ endpointCopy: string;
606
+ endpointCopied: string;
607
+ endpointMissing: string;
608
+ inertBanner: string;
609
+ createButton: string;
610
+ createModalTitle: string;
611
+ scopeLabel: string;
612
+ scopeAll: string;
613
+ expirationLabel: string;
614
+ expirationNever: string;
615
+ expiration30days: string;
616
+ expiration90days: string;
617
+ expirationCustom: string;
618
+ issueButton: string;
619
+ issuing: string;
620
+ revealTitle: string;
621
+ revealHint: string;
622
+ copy: string;
623
+ copied: string;
624
+ done: string;
625
+ loading: string;
626
+ error: string;
627
+ listEmpty: string;
628
+ columnPrefix: string;
629
+ columnScope: string;
630
+ columnCreated: string;
631
+ columnLastUsed: string;
632
+ columnStatus: string;
633
+ lastUsedNever: string;
634
+ statusActive: string;
635
+ statusRevoked: string;
636
+ statusExpired: string;
637
+ revoke: string;
638
+ revokeConfirm: string;
639
+ };
472
640
  public: {
473
641
  back: string;
474
642
  home: string;
@@ -511,9 +679,13 @@ declare const dictionaries: {
511
679
  posts: string;
512
680
  media: string;
513
681
  sites: string;
682
+ users: string;
683
+ mcpTokens: string;
514
684
  viewSite: string;
515
685
  signOut: string;
516
686
  site: string;
687
+ openMenu: string;
688
+ closeMenu: string;
517
689
  };
518
690
  dashboard: {
519
691
  title: string;
@@ -553,6 +725,20 @@ declare const dictionaries: {
553
725
  tagsPlaceholder: string;
554
726
  tagsHint: string;
555
727
  status: string;
728
+ noLayout: string;
729
+ noLayoutHint: string;
730
+ formatStaticLabel: string;
731
+ static: {
732
+ pick: string;
733
+ pickHint: string;
734
+ currentBundle: string;
735
+ pendingBundle: string;
736
+ issuesTitle: string;
737
+ issuesHint: string;
738
+ emptyBundle: string;
739
+ noBundle: string;
740
+ previewHint: string;
741
+ };
556
742
  saveChanges: string;
557
743
  createPost: string;
558
744
  delete: string;
@@ -624,6 +810,25 @@ declare const dictionaries: {
624
810
  label: string;
625
811
  };
626
812
  };
813
+ users: {
814
+ list: {
815
+ title: string;
816
+ description: string;
817
+ columnEmail: string;
818
+ columnRole: string;
819
+ columnActions: string;
820
+ save: string;
821
+ saving: string;
822
+ saved: string;
823
+ cannotEditSelf: string;
824
+ empty: string;
825
+ loading: string;
826
+ error: string;
827
+ roleAdmin: string;
828
+ roleEditor: string;
829
+ roleNone: string;
830
+ };
831
+ };
627
832
  theme: {
628
833
  title: string;
629
834
  activeLabel: string;
@@ -642,6 +847,13 @@ declare const dictionaries: {
642
847
  customizationHint: string;
643
848
  lengthHelp: string;
644
849
  imagePlaceholder: string;
850
+ colorScheme: {
851
+ label: string;
852
+ hint: string;
853
+ auto: string;
854
+ light: string;
855
+ dark: string;
856
+ };
645
857
  };
646
858
  editor: {
647
859
  linkPrompt: string;
@@ -702,6 +914,45 @@ declare const dictionaries: {
702
914
  userExists: string;
703
915
  };
704
916
  };
917
+ mcpTokens: {
918
+ title: string;
919
+ description: string;
920
+ endpointTitle: string;
921
+ endpointCopy: string;
922
+ endpointCopied: string;
923
+ endpointMissing: string;
924
+ inertBanner: string;
925
+ createButton: string;
926
+ createModalTitle: string;
927
+ scopeLabel: string;
928
+ scopeAll: string;
929
+ expirationLabel: string;
930
+ expirationNever: string;
931
+ expiration30days: string;
932
+ expiration90days: string;
933
+ expirationCustom: string;
934
+ issueButton: string;
935
+ issuing: string;
936
+ revealTitle: string;
937
+ revealHint: string;
938
+ copy: string;
939
+ copied: string;
940
+ done: string;
941
+ loading: string;
942
+ error: string;
943
+ listEmpty: string;
944
+ columnPrefix: string;
945
+ columnScope: string;
946
+ columnCreated: string;
947
+ columnLastUsed: string;
948
+ columnStatus: string;
949
+ lastUsedNever: string;
950
+ statusActive: string;
951
+ statusRevoked: string;
952
+ statusExpired: string;
953
+ revoke: string;
954
+ revokeConfirm: string;
955
+ };
705
956
  public: {
706
957
  back: string;
707
958
  home: string;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Config } from 'ampless';
2
2
  import { AmplessOutputs, EffectiveSiteSettings, EffectiveThemeConfig, Ampless } from '@ampless/runtime';
3
- import { L as Locale, D as Dictionary } from './i18n-ByHM_Bho.js';
4
- export { A as AdminLocaleStrings, g as getDictionary, r as resolveLocale, t as translate } from './i18n-ByHM_Bho.js';
3
+ import { L as Locale, D as Dictionary } from './i18n-MWvAMHzn.js';
4
+ export { A as AdminLocaleStrings, g as getDictionary, r as resolveLocale, t as translate } from './i18n-MWvAMHzn.js';
5
5
  import * as _aws_amplify_adapter_nextjs from '@aws-amplify/adapter-nextjs';
6
6
 
7
7
  /**
@@ -24,14 +24,19 @@ interface CreateAdminOpts {
24
24
  cmsConfig: Config;
25
25
  /**
26
26
  * Optional pre-built ampless runtime instance for cross-package
27
- * sharing. When omitted, admin doesn't build one server pages
28
- * (sites list / site edit / theme edit) still need
29
- * `loadSiteSettings` / `loadThemeConfig`, so passing an `ampless`
30
- * here lets admin reuse the same runtime your public pages already
31
- * use. If not provided, the admin's server pages won't be able to
32
- * load site settings.
27
+ * sharing. Accepts either the instance itself OR a thunk (sync or
28
+ * async). The thunk form is the recommended one for the template
29
+ * scaffold's `lib/admin.ts` it lets the consumer break the
30
+ * `lib/admin.ts lib/ampless.ts themes-registry lib/admin.ts`
31
+ * static-import cycle by lazily resolving `ampless` via `import()`
32
+ * inside the thunk body (the module isn't loaded until the first
33
+ * `loadSiteSettings` / `loadThemeConfig` call, by which time all
34
+ * other modules have finished initialising).
35
+ *
36
+ * When omitted, server pages that depend on settings / theme config
37
+ * throw at request time.
33
38
  */
34
- ampless?: Ampless;
39
+ ampless?: Ampless | (() => Ampless | Promise<Ampless>);
35
40
  /**
36
41
  * Locale for admin UI strings. Pass a string code ('en', 'ja') for a
37
42
  * built-in dictionary, or an object literal to override specific
package/dist/index.js CHANGED
@@ -1,10 +1,14 @@
1
1
  import {
2
- ADMIN_SITE_COOKIE,
3
- createMedia,
2
+ ADMIN_SITE_COOKIE
3
+ } from "./chunk-7IR4F7GA.js";
4
+ import {
5
+ createMedia
6
+ } from "./chunk-2ITWLRYF.js";
7
+ import {
4
8
  getDictionary,
5
9
  resolveLocale,
6
10
  translate
7
- } from "./chunk-TJR3ALRJ.js";
11
+ } from "./chunk-OSUTPPAU.js";
8
12
 
9
13
  // src/lib/admin-site.ts
10
14
  import { cookies } from "next/headers";
@@ -80,15 +84,19 @@ function createAdmin(opts) {
80
84
  const amplifyServer = createAmplifyServer(outputs);
81
85
  const auth = createAuthServer(amplifyServer);
82
86
  const media = createMedia(outputs, cmsConfig);
83
- const ampless = amplessIn ?? null;
84
- function requireAmpless() {
85
- if (!ampless) {
87
+ let amplessCache = null;
88
+ async function resolveAmpless() {
89
+ if (amplessCache) return amplessCache;
90
+ if (amplessIn === void 0 || amplessIn === null) {
86
91
  throw new Error(
87
92
  "[@ampless/admin] createAdmin was called without an `ampless` runtime instance, but a method that needs one (loadSiteSettings / loadThemeConfig) was invoked. Pass `ampless` in the `createAdmin` options so admin can reuse your public-side runtime."
88
93
  );
89
94
  }
90
- return ampless;
95
+ const resolved = typeof amplessIn === "function" ? await amplessIn() : amplessIn;
96
+ amplessCache = resolved;
97
+ return resolved;
91
98
  }
99
+ const eagerAmpless = amplessIn !== void 0 && amplessIn !== null && typeof amplessIn !== "function" ? amplessIn : null;
92
100
  return {
93
101
  t: (key, vars) => translate(dict, key, vars),
94
102
  locale,
@@ -99,12 +107,12 @@ function createAdmin(opts) {
99
107
  amplifyServer,
100
108
  currentAdminSiteId: adminSite.currentAdminSiteId,
101
109
  adminSiteOptions: adminSite.adminSiteOptions,
102
- loadSiteSettings: (siteId) => requireAmpless().loadSiteSettings(siteId),
103
- loadThemeConfig: (siteId) => requireAmpless().loadThemeConfig(siteId),
110
+ loadSiteSettings: async (siteId) => (await resolveAmpless()).loadSiteSettings(siteId),
111
+ loadThemeConfig: async (siteId) => (await resolveAmpless()).loadThemeConfig(siteId),
104
112
  publicMediaUrl: media.publicMediaUrl,
105
113
  outputs,
106
114
  cmsConfig,
107
- ampless
115
+ ampless: eagerAmpless
108
116
  };
109
117
  }
110
118
  export {
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Force-invalidate the Next.js fetch cache for a site's settings JSON.
3
+ * Used by the admin theme switcher: writes to KvStore propagate to S3
4
+ * via the trusted processor (~5-10s), and without this call the
5
+ * `revalidate: 60` on the public-side fetch would keep serving the old
6
+ * cached response for up to a minute after the rebuild.
7
+ *
8
+ * The cache tag matches the one used in `theme-active.ts` and
9
+ * `theme-config.ts` (in `@ampless/runtime`): `site-settings:{siteId}`.
10
+ *
11
+ * Uses `updateTag` (Next 16+) — the read-your-own-writes variant of
12
+ * the old `revalidateTag`, which is the right semantics inside a
13
+ * server action (this entire module is `'use server'`).
14
+ */
15
+ declare function invalidateSiteSettingsCache(siteId: string): Promise<void>;
16
+
17
+ export { invalidateSiteSettingsCache };
@@ -0,0 +1,7 @@
1
+ "use server";
2
+ import {
3
+ invalidateSiteSettingsCache
4
+ } from "../chunk-VXEVLHGL.js";
5
+ export {
6
+ invalidateSiteSettingsCache
7
+ };