@hywax/cms 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,5 @@
1
+ export default {
2
+ "slots": {
3
+ "base": "p-0"
4
+ }
5
+ }
@@ -0,0 +1 @@
1
+ export { default as buttonClear } from './button-clear'
@@ -0,0 +1 @@
1
+ export { default as uploraImage } from './uplora-image'
@@ -0,0 +1,5 @@
1
+ export default {
2
+ "slots": {
3
+ "base": ""
4
+ }
5
+ }
package/.nuxt/cms.css ADDED
@@ -0,0 +1 @@
1
+ @source "./cms";
package/dist/module.d.mts CHANGED
@@ -1,6 +1,17 @@
1
1
  import * as _nuxt_schema from '@nuxt/schema';
2
+ export * from '../dist/runtime/types/index.js';
2
3
 
3
4
  interface ModuleOptions {
5
+ /**
6
+ * Name of the module
7
+ * @defaultValue 'cms'
8
+ */
9
+ name?: string;
10
+ /**
11
+ * Prefix for the components
12
+ * @defaultValue 'C'
13
+ */
14
+ prefix?: string;
4
15
  }
5
16
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
6
17
 
package/dist/module.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hywax/cms",
3
- "version": "0.0.0",
3
+ "version": "0.0.2",
4
4
  "configKey": "cms",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.1",
package/dist/module.mjs CHANGED
@@ -1,7 +1,121 @@
1
- import { defineNuxtModule } from '@nuxt/kit';
1
+ import { addTypeTemplate, addTemplate, defineNuxtModule, hasNuxtModule, installModule, createResolver, addComponentsDir, addImportsDir } from '@nuxt/kit';
2
+ import { defu } from 'defu';
3
+ import 'node:url';
4
+ import { kebabCase } from 'scule';
2
5
 
3
6
  const name = "@hywax/cms";
4
- const version = "0.0.0";
7
+ const version = "0.0.2";
8
+
9
+ const buttonClear = {
10
+ slots: {
11
+ base: "p-0"
12
+ }
13
+ };
14
+
15
+ const theme = {
16
+ __proto__: null,
17
+ buttonClear: buttonClear
18
+ };
19
+
20
+ const uploraImage = {
21
+ slots: {
22
+ base: ""
23
+ }
24
+ };
25
+
26
+ const themeProse = {
27
+ __proto__: null,
28
+ uploraImage: uploraImage
29
+ };
30
+
31
+ function getTemplates(options) {
32
+ const templates = [];
33
+ function writeThemeTemplate(theme2, path) {
34
+ for (const component in theme2) {
35
+ templates.push({
36
+ filename: `cms/${path ? `${path}/` : ""}${kebabCase(component)}.ts`,
37
+ write: true,
38
+ getContents: async () => {
39
+ const template = theme2[component];
40
+ const result = typeof template === "function" ? template(options) : template;
41
+ const variants = Object.entries(result.variants || {}).filter(([_, values]) => {
42
+ const keys = Object.keys(values);
43
+ return keys.some((key) => key !== "true" && key !== "false");
44
+ }).map(([key]) => key);
45
+ let json = JSON.stringify(result, null, 2);
46
+ for (const variant of variants) {
47
+ json = json.replace(new RegExp(`("${variant}": "[^"]+")`, "g"), `$1 as typeof ${variant}[number]`);
48
+ json = json.replace(new RegExp(`("${variant}": \\[\\s*)((?:"[^"]+",?\\s*)+)(\\])`, "g"), (_, before, match, after) => {
49
+ const replaced = match.replace(/("[^"]+")/g, `$1 as typeof ${variant}[number]`);
50
+ return `${before}${replaced}${after}`;
51
+ });
52
+ }
53
+ function generateVariantDeclarations(variants2) {
54
+ return variants2.filter((variant) => json.includes(`as typeof ${variant}`)).map((variant) => {
55
+ const keys = Object.keys(result.variants[variant]);
56
+ return `const ${variant} = ${JSON.stringify(keys, null, 2)} as const`;
57
+ });
58
+ }
59
+ return [
60
+ ...generateVariantDeclarations(variants),
61
+ `export default ${json}`
62
+ ].join("\n\n");
63
+ }
64
+ });
65
+ }
66
+ }
67
+ writeThemeTemplate(themeProse, "prose");
68
+ writeThemeTemplate(theme);
69
+ templates.push({
70
+ filename: `cms/prose/index.ts`,
71
+ write: true,
72
+ getContents: () => Object.keys(themeProse).map((component) => `export { default as ${component} } from './${kebabCase(component)}'`).join("\n")
73
+ });
74
+ templates.push({
75
+ filename: "cms.css",
76
+ write: true,
77
+ getContents: () => `@source "./cms";`
78
+ });
79
+ templates.push({
80
+ filename: "cms/index.ts",
81
+ write: true,
82
+ getContents: () => {
83
+ return Object.keys(theme).map((component) => `export { default as ${component} } from './${kebabCase(component)}'`).join("\n");
84
+ }
85
+ });
86
+ templates.push({
87
+ filename: "types/cms.d.ts",
88
+ getContents: () => `import * as cms from '#build/cms'
89
+ import type { TVConfig } from '@nuxt/ui'
90
+
91
+ type AppConfigCMS = TVConfig<typeof cms>
92
+
93
+ declare module '@nuxt/schema' {
94
+ interface AppConfigInput {
95
+ /**
96
+ * CMS theme configuration
97
+ */
98
+ cms?: AppConfigCMS
99
+ }
100
+ }
101
+
102
+ export {}
103
+ `
104
+ });
105
+ return templates;
106
+ }
107
+ function addTemplates(options) {
108
+ const templates = getTemplates(options);
109
+ for (const template of templates) {
110
+ if (template.filename.endsWith(".d.ts")) {
111
+ addTypeTemplate(template);
112
+ } else {
113
+ addTemplate(template);
114
+ }
115
+ }
116
+ }
117
+
118
+ const icons = {};
5
119
 
6
120
  const module = defineNuxtModule({
7
121
  meta: {
@@ -9,8 +123,60 @@ const module = defineNuxtModule({
9
123
  version,
10
124
  configKey: "cms"
11
125
  },
12
- defaults: {},
13
- setup(_options, _nuxt) {
126
+ defaults: {
127
+ name: "cms",
128
+ prefix: "C"
129
+ },
130
+ async setup(options, nuxt) {
131
+ nuxt.options.appConfig.ui = defu(nuxt.options.appConfig.ui || {}, {
132
+ icons
133
+ });
134
+ nuxt.options.ui = defu(nuxt.options.ui || {}, {
135
+ colorMode: true,
136
+ fonts: true
137
+ });
138
+ nuxt.options.colorMode = defu(nuxt.options.colorMode || {}, {
139
+ storageKey: `${options.name}-color-mode`
140
+ });
141
+ nuxt.options.mdc = defu(nuxt.options.mdc || {}, {
142
+ components: {
143
+ map: {
144
+ "uplora-image": "ProseUploraImage"
145
+ }
146
+ }
147
+ });
148
+ nuxt.options.auth = defu(nuxt.options.auth || {}, {
149
+ name: `${options.name}-session`
150
+ });
151
+ if (!hasNuxtModule("@nuxt/ui-pro")) {
152
+ await installModule("@nuxt/ui-pro");
153
+ }
154
+ if (!hasNuxtModule("@nuxtjs/mdc")) {
155
+ await installModule("@nuxtjs/mdc");
156
+ }
157
+ if (!hasNuxtModule("@vueuse/nuxt")) {
158
+ await installModule("@vueuse/nuxt");
159
+ }
160
+ if (!hasNuxtModule("nuxt-auth-utils")) {
161
+ await installModule("nuxt-auth-utils");
162
+ }
163
+ const { resolve } = createResolver(import.meta.url);
164
+ nuxt.options.alias["#cms"] = resolve("./runtime");
165
+ nuxt.options.appConfig.cms = defu(nuxt.options.appConfig.cms || {}, {});
166
+ addComponentsDir({
167
+ path: resolve("./runtime/components"),
168
+ pathPrefix: false,
169
+ prefix: options?.prefix || "C",
170
+ ignore: ["prose/**"]
171
+ });
172
+ addComponentsDir({
173
+ path: resolve("./runtime/components/prose"),
174
+ prefix: "Prose",
175
+ pathPrefix: false,
176
+ global: true
177
+ });
178
+ addImportsDir(resolve("./runtime/composables"));
179
+ addTemplates(options);
14
180
  }
15
181
  });
16
182
 
@@ -0,0 +1,36 @@
1
+ <template>
2
+ <UButton
3
+ :class="ui.base({ class: [props.ui?.base, props.class] })"
4
+ :color="color"
5
+ :variant="variant"
6
+ :size="size"
7
+ :icon="icon || appConfig.ui.icons.close"
8
+ :aria-label="label"
9
+ :disabled="!modelValue"
10
+ @click.stop="emit('update:modelValue', resetValue)"
11
+ />
12
+ </template>
13
+
14
+ <script>
15
+ import theme from "#build/cms/button-clear";
16
+ import { useAppConfig } from "#imports";
17
+ import { computed } from "vue";
18
+ import { tv } from "../utils/tv";
19
+ </script>
20
+
21
+ <script setup>
22
+ const props = defineProps({
23
+ icon: { type: String, required: false },
24
+ label: { type: String, required: false, default: "\u041E\u0447\u0438\u0441\u0442\u0438\u0442\u044C \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435" },
25
+ color: { type: null, required: false, default: "neutral" },
26
+ variant: { type: null, required: false, default: "link" },
27
+ size: { type: null, required: false, default: "sm" },
28
+ resetValue: { type: [String, Number, Boolean, null], required: false, skipCheck: true, default: void 0 },
29
+ class: { type: null, required: false },
30
+ ui: { type: null, required: false }
31
+ });
32
+ const emit = defineEmits(["update:modelValue"]);
33
+ const modelValue = defineModel({ type: [String, Number, Boolean, null], skipCheck: true });
34
+ const appConfig = useAppConfig();
35
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.cms?.buttonClear || {} })());
36
+ </script>
@@ -0,0 +1,35 @@
1
+ import type { AppConfig } from '@nuxt/schema';
2
+ import type { ButtonProps } from '@nuxt/ui';
3
+ import type { ComponentConfig } from '../types';
4
+ import theme from '#build/cms/button-clear';
5
+ export type ButtonClear = ComponentConfig<typeof theme, AppConfig, 'buttonClear'>;
6
+ export type ResetValue = string | number | boolean | null | undefined;
7
+ export interface ButtonClearProps {
8
+ icon?: string;
9
+ label?: string;
10
+ color?: ButtonProps['color'];
11
+ variant?: ButtonProps['variant'];
12
+ size?: ButtonProps['size'];
13
+ resetValue?: ResetValue;
14
+ class?: any;
15
+ ui?: ButtonClear['slots'];
16
+ }
17
+ export interface ButtonClearEmits {
18
+ 'update:modelValue': [ResetValue];
19
+ }
20
+ declare const _default: import("vue").DefineComponent<ButtonClearProps & {
21
+ modelValue?: ResetValue;
22
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
23
+ "update:modelValue": (...args: unknown[]) => any;
24
+ }, string, import("vue").PublicProps, Readonly<ButtonClearProps & {
25
+ modelValue?: ResetValue;
26
+ }> & Readonly<{
27
+ "onUpdate:modelValue"?: ((...args: unknown[]) => any) | undefined;
28
+ }>, {
29
+ size: "xs" | "sm" | "md" | "lg" | "xl";
30
+ color: "primary" | "secondary" | "success" | "info" | "warning" | "error" | "neutral";
31
+ variant: "solid" | "outline" | "soft" | "subtle" | "ghost" | "link";
32
+ label: string;
33
+ resetValue: string | number | boolean | null;
34
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
35
+ export default _default;
@@ -0,0 +1,24 @@
1
+ <template>
2
+ <div :class="ui.base({ class: [props.ui?.base, props.class] })">
3
+ ...
4
+ </div>
5
+ </template>
6
+
7
+ <script>
8
+ import theme from "#build/cms/prose/uplora-image";
9
+ import { useAppConfig } from "#imports";
10
+ import { computed } from "vue";
11
+ import { tv } from "../../utils/tv";
12
+ </script>
13
+
14
+ <script setup>
15
+ const props = defineProps({
16
+ image: { type: String, required: true },
17
+ alt: { type: String, required: true },
18
+ lqip: { type: String, required: false },
19
+ class: { type: null, required: false },
20
+ ui: { type: null, required: false }
21
+ });
22
+ const appConfig = useAppConfig();
23
+ const ui = computed(() => tv({ extend: tv(theme), ...appConfig.cms?.prose?.uploraImage || {} })());
24
+ </script>
@@ -0,0 +1,13 @@
1
+ import type { AppConfig } from '@nuxt/schema';
2
+ import type { ComponentConfig } from '../../types';
3
+ import theme from '#build/cms/prose/uplora-image';
4
+ export type ProseUploraImage = ComponentConfig<typeof theme, AppConfig, 'uploraImage', 'cms.prose'>;
5
+ export interface ProseUploraImageProps {
6
+ image: string;
7
+ alt: string;
8
+ lqip?: string;
9
+ class?: any;
10
+ ui?: ProseUploraImage['slots'];
11
+ }
12
+ declare const _default: import("vue").DefineComponent<ProseUploraImageProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<ProseUploraImageProps> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ export default _default;
@@ -0,0 +1 @@
1
+ @import "@nuxt/ui-pro";@import "#build/cms.css";@source "./components";
@@ -0,0 +1,6 @@
1
+ declare module '#build/app.config' {
2
+ import type { AppConfig } from '@nuxt/schema'
3
+
4
+ const _default: AppConfig
5
+ export default _default
6
+ }
@@ -0,0 +1,2 @@
1
+ export * from '../components/ButtonClear.vue';
2
+ export * from './utils';
@@ -0,0 +1,2 @@
1
+ export * from "../components/ButtonClear.vue";
2
+ export * from "./utils.js";
@@ -0,0 +1,53 @@
1
+ import type { ClassValue, TVCompoundVariants, TVDefaultVariants, TVVariants } from 'tailwind-variants';
2
+ /**
3
+ * Defines the AppConfig object based on the tailwind-variants configuration.
4
+ */
5
+ export type TVConfig<T extends Record<string, any>> = {
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' ? {
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;
10
+ };
11
+ };
12
+ /**
13
+ * Utility type to flatten intersection types for better IDE hover information.
14
+ * @template T The type to flatten.
15
+ */
16
+ type Id<T> = {} & {
17
+ [P in keyof T]: T[P];
18
+ };
19
+ type ComponentVariants<T extends {
20
+ variants?: Record<string, Record<string, any>>;
21
+ }> = {
22
+ [K in keyof T['variants']]: keyof T['variants'][K];
23
+ };
24
+ type ComponentSlots<T extends {
25
+ slots?: Record<string, any>;
26
+ }> = Id<{
27
+ [K in keyof T['slots']]?: ClassValue;
28
+ }>;
29
+ 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'> = A & (U extends 'cms.prose' ? {
31
+ cms?: {
32
+ prose?: {
33
+ [k in K]?: Partial<T>;
34
+ };
35
+ };
36
+ } : {
37
+ [key in Exclude<U, 'cms.prose'>]?: {
38
+ [k in K]?: Partial<T>;
39
+ };
40
+ });
41
+ /**
42
+ * Defines the configuration shape expected for a component.
43
+ * @template T The component's theme imported from `#build/cms/*`.
44
+ * @template A The base AppConfig type from `@nuxt/schema`.
45
+ * @template K The key identifying the component (e.g., 'badge').
46
+ * @template U The top-level key in AppConfig ('cms' or 'cms.prose').
47
+ */
48
+ export type ComponentConfig<T extends Record<string, any>, A extends Record<string, any>, K extends string, U extends 'cms' | 'cms.prose' = 'cms'> = {
49
+ AppConfig: ComponentAppConfig<T, A, K, U>;
50
+ variants: ComponentVariants<T & GetComponentAppConfig<A, U, K>>;
51
+ slots: ComponentSlots<T>;
52
+ };
53
+ export {};
File without changes
@@ -0,0 +1,3 @@
1
+ import type { AcceptableValue as _AcceptableValue } from 'reka-ui';
2
+ export type AcceptableValue = Exclude<_AcceptableValue, Record<string, any>>;
3
+ export * from './tv';
@@ -0,0 +1 @@
1
+ export * from "./tv.js";
@@ -0,0 +1 @@
1
+ export {};
File without changes
@@ -0,0 +1 @@
1
+ export declare const tv: import("tailwind-variants").CreateTV;
@@ -0,0 +1,4 @@
1
+ import appConfig from "#build/app.config";
2
+ import { createTV } from "tailwind-variants";
3
+ const appConfigTv = appConfig;
4
+ export const tv = /* @__PURE__ */ createTV(appConfigTv.ui?.tv);
package/dist/types.d.mts CHANGED
@@ -1,3 +1,5 @@
1
1
  export { default } from './module.mjs'
2
2
 
3
3
  export { type ModuleOptions } from './module.mjs'
4
+
5
+ export * from '../dist/runtime/types/index.js'
package/package.json CHANGED
@@ -1,27 +1,53 @@
1
1
  {
2
2
  "name": "@hywax/cms",
3
3
  "type": "module",
4
- "version": "0.0.1",
4
+ "version": "0.0.2",
5
5
  "description": "Hywax CMS. ⚠️ This package is intended for internal use only.",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/hywax/cms.git"
9
9
  },
10
+ "imports": {
11
+ "#build/cms/*": "./.nuxt/cms/*.ts",
12
+ "#build/cms.css": "./.nuxt/cms.css"
13
+ },
10
14
  "exports": {
11
15
  ".": {
12
- "types": "./dist/types.d.mts",
16
+ "types": "./dist/module.d.mts",
17
+ "style": "./dist/runtime/index.css",
13
18
  "import": "./dist/module.mjs"
19
+ },
20
+ "./runtime/*": "./dist/runtime/*",
21
+ "./utils": {
22
+ "types": "./dist/runtime/utils/index.d.ts",
23
+ "import": "./dist/runtime/utils/index.js"
24
+ },
25
+ "./utils/*": {
26
+ "types": "./dist/runtime/utils/*.d.ts",
27
+ "import": "./dist/runtime/utils/*.js"
14
28
  }
15
29
  },
16
30
  "main": "./dist/module.mjs",
17
31
  "typesVersions": {
18
32
  "*": {
19
33
  ".": [
20
- "./dist/types.d.mts"
34
+ "./dist/module.d.mts"
35
+ ],
36
+ "./runtime/*": [
37
+ "./dist/runtime/*"
38
+ ],
39
+ "./utils": [
40
+ "./dist/runtime/utils/index.d.ts"
41
+ ],
42
+ "./utils/*": [
43
+ "./dist/runtime/utils/*.d.ts"
21
44
  ]
22
45
  }
23
46
  },
47
+ "style": "./dist/runtime/index.css",
24
48
  "files": [
49
+ ".nuxt/cms",
50
+ ".nuxt/cms.css",
25
51
  "dist"
26
52
  ],
27
53
  "dependencies": {
@@ -30,8 +56,11 @@
30
56
  "@nuxt/ui-pro": "^3.1.3",
31
57
  "@nuxtjs/mdc": "^0.17.0",
32
58
  "@unpress/mdc-prosemirror": "0.1.12-beta.2",
59
+ "@vueuse/nuxt": "^13.4.0",
33
60
  "defu": "^6.1.4",
34
- "prosekit": "^0.13.6"
61
+ "nuxt-auth-utils": "^0.5.20",
62
+ "prosekit": "^0.13.6",
63
+ "zod": "^3.25.67"
35
64
  },
36
65
  "devDependencies": {
37
66
  "@antfu/eslint-config": "^4.14.1",
@@ -42,6 +71,7 @@
42
71
  "@nuxt/schema": "^3.17.5",
43
72
  "@nuxt/test-utils": "^3.19.1",
44
73
  "@types/node": "^22.14.0",
74
+ "@vue/test-utils": "^2.4.6",
45
75
  "changelogen": "^0.6.1",
46
76
  "eslint": "^9.29.0",
47
77
  "happy-dom": "^18.0.1",