@promakeai/cli 0.4.6 → 0.5.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 (48) hide show
  1. package/README.md +71 -0
  2. package/dist/index.js +149 -156
  3. package/dist/registry/blog-core.json +7 -26
  4. package/dist/registry/blog-list-page.json +2 -2
  5. package/dist/registry/blog-section.json +1 -1
  6. package/dist/registry/cart-drawer.json +1 -1
  7. package/dist/registry/cart-page.json +1 -1
  8. package/dist/registry/category-section.json +1 -1
  9. package/dist/registry/checkout-page.json +1 -1
  10. package/dist/registry/docs/blog-core.md +12 -13
  11. package/dist/registry/docs/blog-list-page.md +1 -1
  12. package/dist/registry/docs/ecommerce-core.md +10 -13
  13. package/dist/registry/docs/featured-products.md +1 -1
  14. package/dist/registry/docs/post-detail-page.md +2 -2
  15. package/dist/registry/docs/product-detail-page.md +2 -2
  16. package/dist/registry/docs/products-page.md +1 -1
  17. package/dist/registry/ecommerce-core.json +5 -25
  18. package/dist/registry/featured-products.json +2 -2
  19. package/dist/registry/header-centered-pill.json +1 -1
  20. package/dist/registry/header-ecommerce.json +1 -1
  21. package/dist/registry/index.json +0 -1
  22. package/dist/registry/login-page.json +1 -1
  23. package/dist/registry/post-card.json +1 -1
  24. package/dist/registry/post-detail-block.json +1 -1
  25. package/dist/registry/post-detail-page.json +3 -3
  26. package/dist/registry/product-card-detailed.json +1 -1
  27. package/dist/registry/product-card.json +1 -1
  28. package/dist/registry/product-detail-block.json +1 -1
  29. package/dist/registry/product-detail-page.json +3 -3
  30. package/dist/registry/product-detail-section.json +1 -1
  31. package/dist/registry/product-quick-view.json +1 -1
  32. package/dist/registry/products-page.json +2 -2
  33. package/dist/registry/register-page.json +1 -1
  34. package/dist/registry/related-products-block.json +1 -1
  35. package/package.json +4 -2
  36. package/template/README.md +54 -73
  37. package/template/package.json +4 -3
  38. package/template/public/data/database.db +0 -0
  39. package/template/public/data/database.db-shm +0 -0
  40. package/template/public/data/database.db-wal +0 -0
  41. package/template/scripts/init-db.ts +13 -126
  42. package/template/src/App.tsx +8 -5
  43. package/template/src/db/index.ts +20 -0
  44. package/template/src/db/provider.tsx +77 -0
  45. package/template/src/db/schema.json +259 -0
  46. package/template/src/db/types.ts +195 -0
  47. package/template/src/hooks/use-debounced-value.ts +12 -0
  48. package/dist/registry/db.json +0 -129
@@ -0,0 +1,77 @@
1
+ import { useEffect, useState, type ReactNode } from "react";
2
+ import { useTranslation } from "react-i18next";
3
+ import { DbProvider, SqliteAdapter, parseJSONSchema } from "@promakeai/dbreact";
4
+ import constants from "@/constants/constants.json";
5
+ import schemaJson from "./schema.json";
6
+
7
+ const schema = parseJSONSchema(schemaJson as any);
8
+
9
+ interface AppDbProviderProps {
10
+ children: ReactNode;
11
+ }
12
+
13
+ const DEFAULT_LANG = constants?.site?.defaultLanguage || "en";
14
+
15
+ export function AppDbProvider({ children }: AppDbProviderProps) {
16
+ const { i18n } = useTranslation();
17
+ const [adapter, setAdapter] = useState<SqliteAdapter | null>(null);
18
+ const [error, setError] = useState<Error | null>(null);
19
+
20
+ useEffect(() => {
21
+ let cancelled = false;
22
+
23
+ async function loadDb() {
24
+ try {
25
+ const response = await fetch("/data/database.db");
26
+ if (!response.ok) {
27
+ throw new Error(
28
+ `Failed to load database: ${response.status} ${response.statusText}`
29
+ );
30
+ }
31
+
32
+ const buffer = await response.arrayBuffer();
33
+ if (cancelled) return;
34
+
35
+ const dbAdapter = new SqliteAdapter({
36
+ schema,
37
+ defaultLang: DEFAULT_LANG,
38
+ });
39
+
40
+ await dbAdapter.connect();
41
+ await dbAdapter.import(new Uint8Array(buffer));
42
+
43
+ if (!cancelled) {
44
+ setAdapter(dbAdapter);
45
+ }
46
+ } catch (err) {
47
+ if (!cancelled) {
48
+ setError(err instanceof Error ? err : new Error(String(err)));
49
+ }
50
+ }
51
+ }
52
+
53
+ loadDb();
54
+
55
+ return () => {
56
+ cancelled = true;
57
+ };
58
+ }, []);
59
+
60
+ if (error) {
61
+ console.error(error);
62
+ }
63
+
64
+ if (!adapter) {
65
+ return null;
66
+ }
67
+
68
+ return (
69
+ <DbProvider
70
+ adapter={adapter}
71
+ lang={i18n?.language || DEFAULT_LANG}
72
+ fallbackLang={DEFAULT_LANG}
73
+ >
74
+ {children}
75
+ </DbProvider>
76
+ );
77
+ }
@@ -0,0 +1,259 @@
1
+ {
2
+ "name": "promake",
3
+ "languages": [
4
+ "en",
5
+ "tr"
6
+ ],
7
+ "defaultLanguage": "en",
8
+ "tables": {
9
+ "blog_categories": {
10
+ "id": {
11
+ "type": "id"
12
+ },
13
+ "name": {
14
+ "type": "string",
15
+ "nullable": false,
16
+ "translatable": true
17
+ },
18
+ "slug": {
19
+ "type": "string",
20
+ "nullable": false,
21
+ "unique": true
22
+ },
23
+ "description": {
24
+ "type": "text",
25
+ "translatable": true
26
+ },
27
+ "image": {
28
+ "type": "text"
29
+ },
30
+ "created_at": {
31
+ "type": "timestamp"
32
+ },
33
+ "updated_at": {
34
+ "type": "timestamp"
35
+ }
36
+ },
37
+ "posts": {
38
+ "id": {
39
+ "type": "id"
40
+ },
41
+ "title": {
42
+ "type": "string",
43
+ "nullable": false,
44
+ "translatable": true
45
+ },
46
+ "slug": {
47
+ "type": "string",
48
+ "nullable": false,
49
+ "unique": true
50
+ },
51
+ "content": {
52
+ "type": "text",
53
+ "nullable": false,
54
+ "translatable": true
55
+ },
56
+ "excerpt": {
57
+ "type": "text",
58
+ "translatable": true
59
+ },
60
+ "featured_image": {
61
+ "type": "text"
62
+ },
63
+ "images": {
64
+ "type": [
65
+ "string"
66
+ ]
67
+ },
68
+ "author": {
69
+ "type": "string",
70
+ "translatable": true
71
+ },
72
+ "author_avatar": {
73
+ "type": "text"
74
+ },
75
+ "created_at": {
76
+ "type": "timestamp"
77
+ },
78
+ "published_at": {
79
+ "type": "timestamp"
80
+ },
81
+ "updated_at": {
82
+ "type": "timestamp"
83
+ },
84
+ "tags": {
85
+ "type": [
86
+ "string"
87
+ ]
88
+ },
89
+ "categories": {
90
+ "type": [
91
+ "number"
92
+ ],
93
+ "ref": "blog_categories"
94
+ },
95
+ "read_time": {
96
+ "type": "int",
97
+ "default": 0
98
+ },
99
+ "view_count": {
100
+ "type": "int",
101
+ "default": 0
102
+ },
103
+ "featured": {
104
+ "type": "bool",
105
+ "default": false
106
+ },
107
+ "published": {
108
+ "type": "bool",
109
+ "default": true
110
+ },
111
+ "meta_description": {
112
+ "type": "text",
113
+ "translatable": true
114
+ },
115
+ "meta_keywords": {
116
+ "type": "text",
117
+ "translatable": true
118
+ }
119
+ },
120
+ "product_categories": {
121
+ "id": {
122
+ "type": "id"
123
+ },
124
+ "name": {
125
+ "type": "string",
126
+ "nullable": false,
127
+ "translatable": true
128
+ },
129
+ "slug": {
130
+ "type": "string",
131
+ "nullable": false,
132
+ "unique": true
133
+ },
134
+ "description": {
135
+ "type": "text",
136
+ "translatable": true
137
+ },
138
+ "image": {
139
+ "type": "text"
140
+ },
141
+ "parent_id": {
142
+ "type": "int",
143
+ "ref": "product_categories"
144
+ },
145
+ "created_at": {
146
+ "type": "timestamp"
147
+ },
148
+ "updated_at": {
149
+ "type": "timestamp"
150
+ }
151
+ },
152
+ "products": {
153
+ "id": {
154
+ "type": "id"
155
+ },
156
+ "name": {
157
+ "type": "string",
158
+ "nullable": false,
159
+ "translatable": true
160
+ },
161
+ "slug": {
162
+ "type": "string",
163
+ "nullable": false,
164
+ "unique": true
165
+ },
166
+ "description": {
167
+ "type": "text",
168
+ "translatable": true
169
+ },
170
+ "price": {
171
+ "type": "decimal",
172
+ "nullable": false
173
+ },
174
+ "sale_price": {
175
+ "type": "decimal"
176
+ },
177
+ "on_sale": {
178
+ "type": "bool",
179
+ "default": false
180
+ },
181
+ "images": {
182
+ "type": [
183
+ "string"
184
+ ]
185
+ },
186
+ "brand": {
187
+ "type": "string",
188
+ "translatable": true
189
+ },
190
+ "sku": {
191
+ "type": "string"
192
+ },
193
+ "stock": {
194
+ "type": "int",
195
+ "default": 0
196
+ },
197
+ "tags": {
198
+ "type": [
199
+ "string"
200
+ ]
201
+ },
202
+ "categories": {
203
+ "type": [
204
+ "number"
205
+ ],
206
+ "ref": "product_categories"
207
+ },
208
+ "rating": {
209
+ "type": "decimal",
210
+ "default": 0
211
+ },
212
+ "review_count": {
213
+ "type": "int",
214
+ "default": 0
215
+ },
216
+ "featured": {
217
+ "type": "bool",
218
+ "default": false
219
+ },
220
+ "is_new": {
221
+ "type": "bool",
222
+ "default": false
223
+ },
224
+ "published": {
225
+ "type": "bool",
226
+ "default": true
227
+ },
228
+ "specifications": {
229
+ "type": "json"
230
+ },
231
+ "variants": {
232
+ "type": [
233
+ {
234
+ "id": "string",
235
+ "name": "string",
236
+ "value": "string",
237
+ "price?": "number",
238
+ "image?": "string",
239
+ "stockQuantity": "number"
240
+ }
241
+ ]
242
+ },
243
+ "created_at": {
244
+ "type": "timestamp"
245
+ },
246
+ "updated_at": {
247
+ "type": "timestamp"
248
+ },
249
+ "meta_description": {
250
+ "type": "text",
251
+ "translatable": true
252
+ },
253
+ "meta_keywords": {
254
+ "type": "text",
255
+ "translatable": true
256
+ }
257
+ }
258
+ }
259
+ }
@@ -0,0 +1,195 @@
1
+ // Auto-generated from schemas - DO NOT EDIT
2
+
3
+ // From promake schema
4
+ export interface DbBlogCategory {
5
+ id?: number;
6
+ name: string;
7
+ slug: string;
8
+ description?: string;
9
+ image?: string;
10
+ created_at?: string;
11
+ updated_at?: string;
12
+ }
13
+
14
+ export interface DbBlogCategoryTranslation {
15
+ id: number;
16
+ blog_category_id: number;
17
+ language_code: string;
18
+ name: string;
19
+ description?: string;
20
+ created_at?: string;
21
+ }
22
+
23
+ export interface DbBlogCategoryInput {
24
+ id?: number;
25
+ slug: string;
26
+ image?: string;
27
+ created_at?: string;
28
+ updated_at?: string;
29
+ translations?: Record<string, {
30
+ name: string;
31
+ description?: string;
32
+ }>;
33
+ }
34
+
35
+ export interface DbPost {
36
+ id?: number;
37
+ title: string;
38
+ slug: string;
39
+ content: string;
40
+ excerpt?: string;
41
+ featured_image?: string;
42
+ images?: string[];
43
+ author?: string;
44
+ author_avatar?: string;
45
+ created_at?: string;
46
+ published_at?: string;
47
+ updated_at?: string;
48
+ tags?: string[];
49
+ categories?: number[];
50
+ read_time?: number;
51
+ view_count?: number;
52
+ featured?: boolean;
53
+ published?: boolean;
54
+ meta_description?: string;
55
+ meta_keywords?: string;
56
+ }
57
+
58
+ export interface DbPostTranslation {
59
+ id: number;
60
+ post_id: number;
61
+ language_code: string;
62
+ title: string;
63
+ content: string;
64
+ excerpt?: string;
65
+ author?: string;
66
+ meta_description?: string;
67
+ meta_keywords?: string;
68
+ created_at?: string;
69
+ }
70
+
71
+ export interface DbPostInput {
72
+ id?: number;
73
+ slug: string;
74
+ featured_image?: string;
75
+ images?: string[];
76
+ author_avatar?: string;
77
+ created_at?: string;
78
+ published_at?: string;
79
+ updated_at?: string;
80
+ tags?: string[];
81
+ categories?: number[];
82
+ read_time?: number;
83
+ view_count?: number;
84
+ featured?: boolean;
85
+ published?: boolean;
86
+ translations?: Record<string, {
87
+ title: string;
88
+ content: string;
89
+ excerpt?: string;
90
+ author?: string;
91
+ meta_description?: string;
92
+ meta_keywords?: string;
93
+ }>;
94
+ }
95
+
96
+ export interface DbProductCategory {
97
+ id?: number;
98
+ name: string;
99
+ slug: string;
100
+ description?: string;
101
+ image?: string;
102
+ parent_id?: number;
103
+ created_at?: string;
104
+ updated_at?: string;
105
+ }
106
+
107
+ export interface DbProductCategoryTranslation {
108
+ id: number;
109
+ product_category_id: number;
110
+ language_code: string;
111
+ name: string;
112
+ description?: string;
113
+ created_at?: string;
114
+ }
115
+
116
+ export interface DbProductCategoryInput {
117
+ id?: number;
118
+ slug: string;
119
+ image?: string;
120
+ parent_id?: number;
121
+ created_at?: string;
122
+ updated_at?: string;
123
+ translations?: Record<string, {
124
+ name: string;
125
+ description?: string;
126
+ }>;
127
+ }
128
+
129
+ export interface DbProduct {
130
+ id?: number;
131
+ name: string;
132
+ slug: string;
133
+ description?: string;
134
+ price: number;
135
+ sale_price?: number;
136
+ on_sale?: boolean;
137
+ images?: string[];
138
+ brand?: string;
139
+ sku?: string;
140
+ stock?: number;
141
+ tags?: string[];
142
+ categories?: number[];
143
+ rating?: number;
144
+ review_count?: number;
145
+ featured?: boolean;
146
+ is_new?: boolean;
147
+ published?: boolean;
148
+ specifications?: Record<string, unknown>;
149
+ variants?: Array<{ id: string; name: string; value: string; price?: number; image?: string; stockQuantity: number }>;
150
+ created_at?: string;
151
+ updated_at?: string;
152
+ meta_description?: string;
153
+ meta_keywords?: string;
154
+ }
155
+
156
+ export interface DbProductTranslation {
157
+ id: number;
158
+ product_id: number;
159
+ language_code: string;
160
+ name: string;
161
+ description?: string;
162
+ brand?: string;
163
+ meta_description?: string;
164
+ meta_keywords?: string;
165
+ created_at?: string;
166
+ }
167
+
168
+ export interface DbProductInput {
169
+ id?: number;
170
+ slug: string;
171
+ price: number;
172
+ sale_price?: number;
173
+ on_sale?: boolean;
174
+ images?: string[];
175
+ sku?: string;
176
+ stock?: number;
177
+ tags?: string[];
178
+ categories?: number[];
179
+ rating?: number;
180
+ review_count?: number;
181
+ featured?: boolean;
182
+ is_new?: boolean;
183
+ published?: boolean;
184
+ specifications?: Record<string, unknown>;
185
+ variants?: Array<{ id: string; name: string; value: string; price?: number; image?: string; stockQuantity: number }>;
186
+ created_at?: string;
187
+ updated_at?: string;
188
+ translations?: Record<string, {
189
+ name: string;
190
+ description?: string;
191
+ brand?: string;
192
+ meta_description?: string;
193
+ meta_keywords?: string;
194
+ }>;
195
+ }
@@ -0,0 +1,12 @@
1
+ import { useState, useEffect } from "react";
2
+
3
+ export function useDebouncedValue<T>(value: T, delay = 300): T {
4
+ const [debounced, setDebounced] = useState(value);
5
+
6
+ useEffect(() => {
7
+ const timer = setTimeout(() => setDebounced(value), delay);
8
+ return () => clearTimeout(timer);
9
+ }, [value, delay]);
10
+
11
+ return debounced;
12
+ }