@hywax/cms 3.2.1 → 3.4.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.
@@ -4,6 +4,7 @@ const cmsConfig = {
4
4
  "serverDateTime": "YYYY-MM-DD HH:mm:ss"
5
5
  },
6
6
  "prose": {
7
+ "enabled": true,
7
8
  "uploraImage": {
8
9
  "formats": [],
9
10
  "sizes": []
@@ -1,12 +1,13 @@
1
- export { default as ButtonCopyText } from './button-copy-text'
2
- export { default as ButtonDeleteConfirm } from './button-delete-confirm'
3
- export { default as FormPanel } from './form-panel'
4
- export { default as FormPanelAsideSection } from './form-panel-aside-section'
5
- export { default as FormPanelSection } from './form-panel-section'
6
- export { default as FormSeo } from './form-seo'
7
- export { default as FormSlug } from './form-slug'
8
- export { default as FormUploraImage } from './form-uplora-image'
9
- export { default as ModalConfirm } from './modal-confirm'
10
- export { default as TablePanel } from './table-panel'
11
- export { default as TableSearchInput } from './table-search-input'
12
- export { default as UploraImage } from './uplora-image'
1
+ export { default as buttonCopyText } from './button-copy-text'
2
+ export { default as buttonDeleteConfirm } from './button-delete-confirm'
3
+ export { default as formPanel } from './form-panel'
4
+ export { default as formPanelAsideSection } from './form-panel-aside-section'
5
+ export { default as formPanelSection } from './form-panel-section'
6
+ export { default as formSeo } from './form-seo'
7
+ export { default as formSlug } from './form-slug'
8
+ export { default as formUploraImage } from './form-uplora-image'
9
+ export { default as modalConfirm } from './modal-confirm'
10
+ export { default as tablePanel } from './table-panel'
11
+ export { default as tableSearchInput } from './table-search-input'
12
+ export { default as uploraImage } from './uplora-image'
13
+ export * as prose from './prose'
package/.nuxt/cms.css CHANGED
@@ -1,8 +1,5 @@
1
- @source "./cms/autocomplete-select.ts";
2
- @source "./cms/layout.ts";
3
- @source "./cms/ms.ts";
1
+ @source "./cms/prose";
4
2
  @source "./cms/form-panel.ts";
5
- @source "./cms/editor-full.ts";
6
3
  @source "./cms/form-panel-section.ts";
7
4
  @source "./cms/form-slug.ts";
8
5
  @source "./cms/form-uplora-image.ts";
@@ -11,10 +8,5 @@
11
8
  @source "./cms/table-panel.ts";
12
9
  @source "./cms/modal-confirm.ts";
13
10
  @source "./cms/table-search-input.ts";
14
- @source "./cms/table-preview-seo.ts";
15
- @source "./cms/ms-core-options.ts";
16
- @source "./cms/ms-nuxt-context.ts";
17
- @source "./cms/date-picker.ts";
18
- @source "./cms/ss.ts";
19
11
 
20
12
 
package/dist/module.d.mts CHANGED
@@ -54,6 +54,7 @@ interface CMSCoreOptions {
54
54
  * Prose configuration
55
55
  */
56
56
  prose?: {
57
+ enabled?: boolean;
57
58
  uploraImage?: {
58
59
  formats?: ImageFormat[];
59
60
  sizes?: ImageSize[];
package/dist/module.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hywax/cms",
3
- "version": "3.2.1",
3
+ "version": "3.4.0",
4
4
  "configKey": "cms",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
package/dist/module.mjs CHANGED
@@ -3,11 +3,11 @@ import { fileURLToPath } from 'node:url';
3
3
  import { dirname, join } from 'pathe';
4
4
  import { readFile, writeFile } from 'node:fs/promises';
5
5
  import { defu } from 'defu';
6
- import { pascalCase, kebabCase } from 'scule';
6
+ import { pascalCase, kebabCase, camelCase } from 'scule';
7
7
  import { globSync } from 'tinyglobby';
8
8
 
9
9
  const name = "@hywax/cms";
10
- const version = "3.2.1";
10
+ const version = "3.4.0";
11
11
 
12
12
  function createContext(options, nuxt) {
13
13
  const { resolve } = createResolver(import.meta.url);
@@ -18,7 +18,8 @@ function createContext(options, nuxt) {
18
18
  resolve,
19
19
  distDir,
20
20
  runtimeDir,
21
- nuxt
21
+ nuxt,
22
+ detectedComponents: /* @__PURE__ */ new Set()
22
23
  };
23
24
  }
24
25
 
@@ -84,6 +85,7 @@ const defaultModuleOptions = {
84
85
  serverDateTime: "YYYY-MM-DD HH:mm:ss"
85
86
  },
86
87
  prose: {
88
+ enabled: true,
87
89
  uploraImage: {
88
90
  formats: [],
89
91
  sizes: []
@@ -91,7 +93,7 @@ const defaultModuleOptions = {
91
93
  }
92
94
  };
93
95
 
94
- function prepareAutoImports({ resolve, options, nuxt }) {
96
+ async function prepareAutoImports({ resolve, options, nuxt }) {
95
97
  const cmsConfigPath = resolve(nuxt.options.buildDir, "cms/config");
96
98
  const httpStatusesPath = resolve(nuxt.options.buildDir, "cms/http-statuses");
97
99
  addComponentsDir({
@@ -217,7 +219,7 @@ function resolveComponentDependencies(component, dependencyGraph, resolved = /*
217
219
  }
218
220
  return resolved;
219
221
  }
220
- async function detectUsedComponents(dirs, prefix, componentDir, includeComponents) {
222
+ async function detectUsedComponents([dirs, type], prefix, componentDir, includeComponents) {
221
223
  const detectedComponents = /* @__PURE__ */ new Set();
222
224
  if (includeComponents && includeComponents.length > 0) {
223
225
  for (const component of includeComponents) {
@@ -225,15 +227,10 @@ async function detectUsedComponents(dirs, prefix, componentDir, includeComponent
225
227
  }
226
228
  }
227
229
  const componentPattern = new RegExp(`<(?:Lazy)?${prefix}([A-Z][a-zA-Z]+)|\\b(?:Lazy)?${prefix}([A-Z][a-zA-Z]+)\\b`, "g");
228
- for (const dir of dirs) {
229
- const appFiles = globSync(["**/*.{vue,ts,js,tsx,jsx}"], {
230
- cwd: dir,
231
- ignore: ["node_modules/**", ".nuxt/**", "dist/**"]
232
- });
233
- for (const file of appFiles) {
230
+ if (type === "files") {
231
+ for (const file of dirs) {
234
232
  try {
235
- const filePath = join(dir, file);
236
- const content = await readFile(filePath, "utf-8");
233
+ const content = await readFile(file, "utf-8");
237
234
  const matches = content.matchAll(componentPattern);
238
235
  for (const match of matches) {
239
236
  const componentName = match[1] || match[2];
@@ -244,6 +241,27 @@ async function detectUsedComponents(dirs, prefix, componentDir, includeComponent
244
241
  } catch {
245
242
  }
246
243
  }
244
+ } else if (type === "dirs") {
245
+ for (const dir of dirs) {
246
+ const appFiles = globSync(["**/*.{vue,ts,js,tsx,jsx}"], {
247
+ cwd: dir,
248
+ ignore: ["node_modules/**", ".nuxt/**", "dist/**"]
249
+ });
250
+ for (const file of appFiles) {
251
+ try {
252
+ const filePath = join(dir, file);
253
+ const content = await readFile(filePath, "utf-8");
254
+ const matches = content.matchAll(componentPattern);
255
+ for (const match of matches) {
256
+ const componentName = match[1] || match[2];
257
+ if (componentName) {
258
+ detectedComponents.add(componentName);
259
+ }
260
+ }
261
+ } catch {
262
+ }
263
+ }
264
+ }
247
265
  }
248
266
  if (detectedComponents.size === 0) {
249
267
  return void 0;
@@ -259,7 +277,7 @@ async function detectUsedComponents(dirs, prefix, componentDir, includeComponent
259
277
  return allComponents;
260
278
  }
261
279
 
262
- async function prepareMergeConfigs({ nuxt, options, resolve }) {
280
+ async function prepareMergeConfigs({ nuxt, options, resolve, detectedComponents: contextDetectedComponents }) {
263
281
  nuxt.options.experimental = defu(nuxt.options.experimental || {}, {
264
282
  typedPages: true
265
283
  });
@@ -330,7 +348,7 @@ async function prepareMergeConfigs({ nuxt, options, resolve }) {
330
348
  }
331
349
  });
332
350
  const detectedComponents = await detectUsedComponents(
333
- [resolve("./runtime/components"), resolve("./runtime/composables")],
351
+ [[...contextDetectedComponents].map((component) => resolve(`./runtime/components/${component}.vue`)), "files"],
334
352
  "U",
335
353
  resolve("./runtime/components")
336
354
  );
@@ -362,7 +380,7 @@ async function prepareMergeConfigs({ nuxt, options, resolve }) {
362
380
  nuxt.options.vite = defu(nuxt.options.vite || {}, {
363
381
  optimizeDeps: {
364
382
  include: [
365
- "@unovis/vue",
383
+ ...options.unovis ? ["@unovis/vue"] : [],
366
384
  "@tanstack/vue-table",
367
385
  "@uplora/formats",
368
386
  "@nuxt/ui/utils/editor",
@@ -394,7 +412,7 @@ async function prepareMergeConfigs({ nuxt, options, resolve }) {
394
412
  });
395
413
  }
396
414
 
397
- function prepareServerRoutes({ resolve }) {
415
+ async function prepareServerRoutes({ resolve }) {
398
416
  addServerHandler({
399
417
  route: "/api/_uplora",
400
418
  method: "post",
@@ -540,22 +558,18 @@ const uploraImage$1 = {
540
558
 
541
559
  const theme = {
542
560
  __proto__: null,
543
- ButtonCopyText: buttonCopyText,
544
- ButtonDeleteConfirm: buttonDeleteConfirm,
545
- FormPanel: formPanel,
546
- FormPanelAsideSection: formPanelAsideSection,
547
- FormPanelSection: formPanelSection,
548
- FormSeo: formSeo,
549
- FormSlug: formSlug,
550
- FormUploraImage: formUploraImage,
551
- ModalConfirm: modalConfirm,
552
- TablePanel: tablePanel,
553
- TableSearchInput: tableSearchInput,
554
- UploraImage: uploraImage$1
555
- };
556
-
557
- const themeEditor = {
558
- __proto__: null
561
+ buttonCopyText: buttonCopyText,
562
+ buttonDeleteConfirm: buttonDeleteConfirm,
563
+ formPanel: formPanel,
564
+ formPanelAsideSection: formPanelAsideSection,
565
+ formPanelSection: formPanelSection,
566
+ formSeo: formSeo,
567
+ formSlug: formSlug,
568
+ formUploraImage: formUploraImage,
569
+ modalConfirm: modalConfirm,
570
+ tablePanel: tablePanel,
571
+ tableSearchInput: tableSearchInput,
572
+ uploraImage: uploraImage$1
559
573
  };
560
574
 
561
575
  const uploraImage = {
@@ -569,7 +583,7 @@ const themeProse = {
569
583
  uploraImage: uploraImage
570
584
  };
571
585
 
572
- function getAppTemplates({ options, resolve, nuxt }) {
586
+ async function getAppTemplates({ options, resolve, nuxt, detectedComponents: contextDetectedComponents }) {
573
587
  const templates = [];
574
588
  let previousDetectedComponents;
575
589
  function writeThemeTemplate(theme2, path) {
@@ -607,11 +621,11 @@ function getAppTemplates({ options, resolve, nuxt }) {
607
621
  }
608
622
  }
609
623
  async function generateSources() {
610
- const sources = [];
624
+ const sources2 = [];
611
625
  const layers = getLayerDirectories(nuxt).map((layer) => layer.app);
612
626
  if (options.componentDetection) {
613
627
  const detectedComponents = await detectUsedComponents(
614
- layers,
628
+ [layers, "dirs"],
615
629
  options.componentsPrefix,
616
630
  resolve("./runtime/components"),
617
631
  Array.isArray(options.componentDetection) ? options.componentDetection : void 0
@@ -628,40 +642,43 @@ function getAppTemplates({ options, resolve, nuxt }) {
628
642
  logger.success(`CMS detected ${detectedComponents.size} components in use (including dependencies)`);
629
643
  }
630
644
  previousDetectedComponents = detectedComponents;
645
+ if (options.prose?.enabled) {
646
+ sources2.push('@source "./cms/prose";');
647
+ }
631
648
  for (const component of detectedComponents) {
632
649
  const kebabComponent = kebabCase(component);
633
- sources.push(`@source "./cms/${kebabComponent}.ts";`);
650
+ const camelComponent = camelCase(component);
651
+ if (theme[camelComponent]) {
652
+ sources2.push(`@source "./cms/${kebabComponent}.ts";`);
653
+ contextDetectedComponents.add(component);
654
+ }
634
655
  }
635
656
  } else {
636
657
  if (!previousDetectedComponents || previousDetectedComponents.size > 0) {
637
658
  logger.info("CMS detected no components in use, including all components");
638
659
  }
639
660
  previousDetectedComponents = /* @__PURE__ */ new Set();
640
- sources.push('@source "./cms";');
661
+ sources2.push('@source "./cms";');
641
662
  }
642
663
  } else {
643
- sources.push('@source "./cms";');
664
+ sources2.push('@source "./cms";');
644
665
  }
645
- return sources.join("\n");
666
+ return sources2.join("\n");
667
+ }
668
+ if (options.prose?.enabled) {
669
+ templates.push({
670
+ filename: `cms/prose/index.ts`,
671
+ write: true,
672
+ getContents: () => Object.keys(themeProse).map((component) => `export { default as ${component} } from './${kebabCase(component)}'`).join("\n")
673
+ });
674
+ writeThemeTemplate(themeProse, "prose");
646
675
  }
647
- writeThemeTemplate(themeProse, "prose");
648
- writeThemeTemplate(themeProse, "editor");
649
676
  writeThemeTemplate(theme);
650
- templates.push({
651
- filename: `cms/prose/index.ts`,
652
- write: true,
653
- getContents: () => Object.keys(themeProse).map((component) => `export { default as ${component} } from './${kebabCase(component)}'`).join("\n")
654
- });
655
- templates.push({
656
- filename: `cms/editor/index.ts`,
657
- write: true,
658
- getContents: () => Object.keys(themeEditor).map((component) => `export { default as ${component} } from './${kebabCase(component)}'`).join("\n")
659
- });
677
+ const sources = await generateSources();
660
678
  templates.push({
661
679
  filename: "cms.css",
662
680
  write: true,
663
681
  getContents: async () => {
664
- const sources = await generateSources();
665
682
  return `${sources}
666
683
  ${options.unovis ? `
667
684
  @layer components {
@@ -699,24 +716,27 @@ ${options.unovis ? `
699
716
  templates.push({
700
717
  filename: "cms/index.ts",
701
718
  write: true,
702
- getContents: () => {
703
- return Object.keys(theme).map((component) => `export { default as ${component} } from './${kebabCase(component)}'`).join("\n");
704
- }
719
+ getContents: () => [
720
+ ...Object.keys(theme).map((component) => `export { default as ${component} } from './${kebabCase(component)}'`),
721
+ ...options.prose?.enabled ? [`export * as prose from './prose'`] : []
722
+ ].join("\n")
705
723
  });
706
724
  templates.push({
707
725
  filename: "types/cms.d.ts",
708
726
  getContents: () => `import * as cms from '#build/cms'
709
- import type { TVConfig } from '@nuxt/ui'
727
+ import type { TVConfig } from '@hywax/cms'
710
728
  import type { RouteLocationRaw } from 'vue-router'
711
729
 
712
- type AppConfigCMS = TVConfig<typeof cms>
730
+ type AppConfigCMS = {
731
+
732
+ } & TVConfig<typeof cms>
713
733
 
714
734
  declare module '@nuxt/schema' {
715
735
  interface AppConfigInput {
716
736
  /**
717
737
  * CMS theme configuration
718
738
  */
719
- cmsRuntime?: AppConfigCMS
739
+ cms?: AppConfigCMS
720
740
  }
721
741
  }
722
742
 
@@ -751,8 +771,8 @@ function getServerTemplates(_context) {
751
771
  const templates = [];
752
772
  return templates;
753
773
  }
754
- function prepareTemplates(context) {
755
- const appTemplates = getAppTemplates(context);
774
+ async function prepareTemplates(context) {
775
+ const appTemplates = await getAppTemplates(context);
756
776
  const serverTemplates = getServerTemplates();
757
777
  for (const template of appTemplates) {
758
778
  if (template.filename.endsWith(".d.ts")) {
@@ -792,11 +812,16 @@ const module$1 = defineNuxtModule({
792
812
  defaults: defaultModuleOptions,
793
813
  async setup(options, nuxt) {
794
814
  const context = createContext(options, nuxt);
795
- await prepareMergeConfigs(context);
796
- prepareTemplates(context);
797
- prepareAutoImports(context);
798
- prepareServerRoutes(context);
799
- await prepareGenerateEnv(context);
815
+ const prepareHandlers = [
816
+ prepareTemplates,
817
+ prepareMergeConfigs,
818
+ prepareAutoImports,
819
+ prepareServerRoutes,
820
+ prepareGenerateEnv
821
+ ];
822
+ for (const handler of prepareHandlers) {
823
+ await handler(context);
824
+ }
800
825
  }
801
826
  });
802
827
 
@@ -1 +1 @@
1
- @import "@nuxt/ui";@import "#build/cms.css";@source "./components";@source "./editor";@source "./prose";
1
+ @import "@nuxt/ui";@import "#build/cms.css";@source "./components";
@@ -39,5 +39,5 @@ export * from './date';
39
39
  export * from './image';
40
40
  export * from './query';
41
41
  export * from './seo';
42
- export type { ComponentSlots, ComponentVariants } from './tv';
42
+ export * from './tv';
43
43
  export * from './utils';
@@ -39,4 +39,5 @@ export * from "./date.js";
39
39
  export * from "./image.js";
40
40
  export * from "./query.js";
41
41
  export * from "./seo.js";
42
+ export * from "./tv.js";
42
43
  export * from "./utils.js";
@@ -4,11 +4,18 @@ import type { ClassValue, TVCompoundVariants, TVDefaultVariants, TVVariants } fr
4
4
  */
5
5
  export type TVConfig<T extends Record<string, any>> = {
6
6
  [P in keyof T]?: {
7
- [K in keyof T[P] as K extends 'base' | 'slots' | 'variants' | 'compoundVariants' | 'defaultVariants' ? K : never]?: K extends 'base' ? ClassValue : K extends 'slots' ? {
7
+ [K in keyof T[P] as K extends 'base' | 'slots' | 'variants' | 'defaultVariants' ? K : never]?: K extends 'base' ? ClassValue : K extends 'slots' ? {
8
8
  [S in keyof T[P]['slots']]?: ClassValue;
9
- } : K extends 'variants' ? TVVariants<T[P]['slots'], ClassValue, T[P]['variants']> : K extends 'compoundVariants' ? TVCompoundVariants<T[P]['variants'], T[P]['slots'], ClassValue, object, undefined> : K extends 'defaultVariants' ? TVDefaultVariants<T[P]['variants'], T[P]['slots'], object, undefined> : never;
9
+ } : K extends 'variants' ? TVVariants<T[P]['slots'], ClassValue, WidenVariantsValues<T[P]['variants']>> : K extends 'defaultVariants' ? TVDefaultVariants<WidenVariantsValues<T[P]['variants']>, T[P]['slots'], object, undefined> : never;
10
+ };
11
+ } & {
12
+ [P in keyof T]?: {
13
+ compoundVariants?: TVCompoundVariants<WidenVariantsValues<T[P]['variants']>, T[P]['slots'], ClassValue, object, undefined>;
10
14
  };
11
15
  };
16
+ type WidenVariantsValues<V extends Record<string, any> | undefined> = V extends Record<string, any> ? V & {
17
+ [K in keyof V]: V[K] extends Record<string, any> ? V[K] & Record<string & {}, any> : V[K];
18
+ } : V;
12
19
  /**
13
20
  * Utility type to flatten intersection types for better IDE hover information.
14
21
  * @template T The type to flatten.
@@ -26,21 +33,20 @@ export type ComponentSlots<T extends {
26
33
  }> = Id<{
27
34
  [K in keyof T['slots']]?: ClassValue;
28
35
  }>;
36
+ type ComponentUI<T extends {
37
+ slots?: Record<string, any>;
38
+ }> = Id<{
39
+ [K in keyof Required<T['slots']>]: (props?: Record<string, any>) => string;
40
+ }>;
29
41
  type GetComponentAppConfig<A, U extends string, K extends string> = A extends Record<U, Record<K, any>> ? A[U][K] : object;
30
- type ComponentAppConfig<T, A extends Record<string, any>, K extends string, U extends string = 'cms' | 'cms.prose' | 'cms.editor'> = A & (U extends 'cms.prose' ? {
42
+ type ComponentAppConfig<T, A extends Record<string, any>, K extends string, U extends string = 'cms' | 'cms.prose'> = A & (U extends 'cms.prose' ? {
31
43
  cms?: {
32
44
  prose?: {
33
45
  [k in K]?: Partial<T>;
34
46
  };
35
47
  };
36
- } : U extends 'cms.editor' ? {
37
- cms?: {
38
- editor?: {
39
- [k in K]?: Partial<T>;
40
- };
41
- };
42
48
  } : {
43
- [key in Exclude<U, 'cms.prose' | 'cms.editor'>]?: {
49
+ [key in Exclude<U, 'cms.prose'>]?: {
44
50
  [k in K]?: Partial<T>;
45
51
  };
46
52
  });
@@ -51,9 +57,10 @@ type ComponentAppConfig<T, A extends Record<string, any>, K extends string, U ex
51
57
  * @template K The key identifying the component (e.g., 'badge').
52
58
  * @template U The top-level key in AppConfig ('cms' or 'cms.prose').
53
59
  */
54
- export type ComponentConfig<T extends Record<string, any>, A extends Record<string, any>, K extends string, U extends 'cms' | 'cms.prose' | 'cms.editor' = 'cms'> = {
60
+ export type ComponentConfig<T extends Record<string, any>, A extends Record<string, any>, K extends string, U extends 'cms' | 'cms.prose' = 'cms'> = {
55
61
  AppConfig: ComponentAppConfig<T, A, K, U>;
56
62
  variants: ComponentVariants<T & GetComponentAppConfig<A, U, K>>;
57
63
  slots: ComponentSlots<T>;
64
+ ui: ComponentUI<T>;
58
65
  };
59
66
  export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@hywax/cms",
3
3
  "type": "module",
4
- "version": "3.2.1",
4
+ "version": "3.4.0",
5
5
  "description": "Hywax CMS. ⚠️ This package is intended for internal use only.",
6
6
  "imports": {
7
7
  "#build/cms/*": "./.nuxt/cms/*.ts",
@@ -85,8 +85,8 @@
85
85
  },
86
86
  "devDependencies": {
87
87
  "@antfu/eslint-config": "^6.7.3",
88
- "@commitlint/cli": "^20.3.0",
89
- "@commitlint/config-conventional": "^20.3.0",
88
+ "@commitlint/cli": "^20.3.1",
89
+ "@commitlint/config-conventional": "^20.3.1",
90
90
  "@nuxt/devtools": "^3.1.1",
91
91
  "@nuxt/module-builder": "^1.0.2",
92
92
  "@nuxt/schema": "^4.2.2",
File without changes
@@ -1,5 +0,0 @@
1
- export default {
2
- "slots": {
3
- "base": ""
4
- }
5
- }