siteon-registry 1.4.1

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 (38) hide show
  1. package/Readme.md +312 -0
  2. package/bun.lock +80 -0
  3. package/dist/Readme.md +112 -0
  4. package/dist/index.js +1532 -0
  5. package/dist/package.json +21 -0
  6. package/form-fields-example.md +310 -0
  7. package/instructions.md +123 -0
  8. package/package.json +36 -0
  9. package/postbuild.js +17 -0
  10. package/src/commands/init.ts +462 -0
  11. package/src/generators/index.ts +325 -0
  12. package/src/generators/templates/config-js.ts +35 -0
  13. package/src/generators/templates/config.ts +59 -0
  14. package/src/generators/templates/form-file.ts +360 -0
  15. package/src/generators/templates/get-media-js.ts +97 -0
  16. package/src/generators/templates/get-media-ts.ts +61 -0
  17. package/src/generators/templates/get-metadata-js.ts +180 -0
  18. package/src/generators/templates/get-metadata-ts.ts +92 -0
  19. package/src/generators/templates/http-client-js.ts +65 -0
  20. package/src/generators/templates/http-client-ts.ts +65 -0
  21. package/src/generators/templates/index-files.ts +209 -0
  22. package/src/generators/templates/media-ts.ts +252 -0
  23. package/src/generators/templates/public-form-file.ts +870 -0
  24. package/src/generators/templates/siteon-core-js.ts +280 -0
  25. package/src/generators/templates/siteon-core-static.ts +156 -0
  26. package/src/generators/templates/siteon-core-ts.ts +197 -0
  27. package/src/generators/templates/siteon-image-tsx.ts +154 -0
  28. package/src/generators/templates/static.ts +206 -0
  29. package/src/generators/templates/types-ts.ts +125 -0
  30. package/src/generators/type-mapper.ts +134 -0
  31. package/src/index.ts +21 -0
  32. package/src/types.ts +173 -0
  33. package/src/utils/api.ts +157 -0
  34. package/src/utils/dependencies.ts +88 -0
  35. package/src/utils/files.ts +183 -0
  36. package/src/utils/prompts.ts +220 -0
  37. package/src/utils/version.ts +5 -0
  38. package/tsconfig.json +17 -0
package/Readme.md ADDED
@@ -0,0 +1,312 @@
1
+ # Siteon Registry CLI
2
+
3
+ A CLI tool to generate type-safe API clients for Siteon workspaces. Similar to shadcn/ui, this tool generates code directly into your project that you own and can customize.
4
+
5
+ ## Installation
6
+
7
+ Since this is a private GitHub repository, you can run the CLI directly using:
8
+
9
+ 1. Using npx
10
+
11
+ ```bash
12
+ npx https://github.com/compitcomds/siteon-registry init
13
+ # or
14
+ npx github:compitcomds/siteon-registry init
15
+ ```
16
+
17
+ 2. Using pnpm dlx
18
+
19
+ ```bash
20
+ pnpm dlx https://github.com/compitcomds/siteon-registry init
21
+ # or
22
+ pnpm dlx github:compitcomds/siteon-registry#main init
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ ### Initialize in your project
28
+
29
+ Run the `init` command in your project root:
30
+
31
+ ```bash
32
+ siteon init
33
+ ```
34
+
35
+ You'll be prompted for:
36
+
37
+ 1. **Workspace ID** - Your Siteon workspace ID
38
+ 2. **Email & Password** - Your Siteon credentials (ADMIN access required)
39
+ 3. **Output Directory** - Where to place generated files (default: `src` if exists, otherwise root)
40
+ 4. **Project Type**:
41
+ - `Static` - Vanilla HTML/CSS/JS (ES modules)
42
+ - `Framework` - React, Next.js, Vue, Vite, etc.
43
+ 5. **Framework** (if framework selected) - Next.js, Vite, React, Vue, or Other
44
+ 6. **Language** (if framework) - TypeScript or JavaScript
45
+ 7. **HTTP Client** (if framework) - Fetch (native) or Axios
46
+ 8. **Config Storage** (if framework) - Environment variables (.env) or config file
47
+ 9. **React Cache** (if React-based) - Use React's `cache` function for caching (React 18+)
48
+ 10. **Form Selection** - All forms or select specific ones
49
+
50
+ ## Generated Structure
51
+
52
+ ```
53
+ your-project/
54
+ ├── siteon.config.json # CLI configuration
55
+ ├── .env # (optional) Environment variables
56
+ └── src/
57
+ └── siteon/
58
+ ├── index.ts # Main entry point
59
+ ├── config.ts # Configuration (workspace ID, base URL)
60
+ ├── types.ts # Type definitions
61
+ ├── http-client.ts # HTTP client (axios or fetch)
62
+ ├── get-metadata.ts # Base fetch function
63
+ ├── get-media.ts # Media helper functions
64
+ └── forms/
65
+ ├── index.ts # Re-exports all forms
66
+ ├── portfolio.ts # Generated form file
67
+ └── blog-post.ts # Generated form file
68
+ ```
69
+
70
+ ## Generated Code Example
71
+
72
+ For each form, the CLI generates strongly typed fetchers:
73
+
74
+ ```typescript
75
+ // TypeScript example for a "Portfolio" form
76
+ import { getMetaData } from "../get-metadata";
77
+ import type { ResponseType, ResponseDataType, QueryParams } from "../types";
78
+ import { cache } from "react"; // if using React cache
79
+
80
+ export type PortfolioDataType = {
81
+ slug: string;
82
+ title: string;
83
+ featured_image: string[];
84
+ category: "Web Design" | "Graphic Design" | "Video Production";
85
+ };
86
+
87
+ export type PortfolioResolvedDataType = {
88
+ slug: string;
89
+ title: string;
90
+ featured_image: string[];
91
+ category: ResolvedRelation; // When resolveRelations is true
92
+ };
93
+
94
+ export type PortfolioQueryOptions = Omit<QueryParams, "resolveRelations"> & {
95
+ resolveRelations?: boolean;
96
+ };
97
+
98
+ // Fetch all items with full query options
99
+ export async function getAllPortfolio(
100
+ options?: PortfolioQueryOptions & { resolveRelations?: false },
101
+ ): Promise<ResponseType<PortfolioDataType>>;
102
+ export async function getAllPortfolio(
103
+ options: PortfolioQueryOptions & { resolveRelations: true },
104
+ ): Promise<ResponseType<PortfolioResolvedDataType>>;
105
+ export async function getAllPortfolio(options: PortfolioQueryOptions = {}) {
106
+ // Implementation
107
+ }
108
+
109
+ // Fetch by slug (with optional React cache)
110
+ export const getPortfolioBySlug = cache(
111
+ async (slug: string, options: { resolveRelations?: boolean } = {}) => {
112
+ // Implementation
113
+ },
114
+ );
115
+ ```
116
+
117
+ ## Usage in Your App
118
+
119
+ ### Basic Usage
120
+
121
+ ```typescript
122
+ import { getAllPortfolio, getPortfolioBySlug } from "@/siteon";
123
+
124
+ // Fetch all portfolio items
125
+ const { data, pagination } = await getAllPortfolio();
126
+
127
+ // Fetch with filters and ordering
128
+ const { data } = await getAllPortfolio({
129
+ filters: {
130
+ "data.category": { equals: "Web Design" },
131
+ },
132
+ orderBy: [{ field: "order", direction: "asc" }],
133
+ page: 1,
134
+ pageSize: 10,
135
+ });
136
+
137
+ // Fetch with resolved relations
138
+ const { data } = await getAllPortfolio({ resolveRelations: true });
139
+
140
+ // Fetch single item by slug
141
+ const portfolio = await getPortfolioBySlug("my-project");
142
+
143
+ // Fetch single item by slug with resolved relations
144
+ const portfolio = await getPortfolioBySlug("my-project", {
145
+ resolveRelations: true,
146
+ });
147
+ ```
148
+
149
+ ### Filtering by Relation
150
+
151
+ To filter by a relation field (e.g., get all blogs in a specific category):
152
+
153
+ ```typescript
154
+ import { getAllBlog } from "@/siteon";
155
+
156
+ // Filter by category relation ID
157
+ const { data } = await getAllBlog({
158
+ filters: {
159
+ "data.category": { equals: "categoryId123" },
160
+ },
161
+ });
162
+
163
+ // Multiple conditions
164
+ const { data } = await getAllBlog({
165
+ filters: {
166
+ AND: {
167
+ "data.category": { equals: "categoryId123" },
168
+ "data.published": { equals: true },
169
+ },
170
+ },
171
+ });
172
+ ```
173
+
174
+ ### With Media Resolution
175
+
176
+ ```typescript
177
+ import { getAllPortfolio, getMediaByIds } from "@/siteon";
178
+
179
+ const { data } = await getAllPortfolio();
180
+
181
+ // Resolve media IDs to URLs
182
+ for (const item of data) {
183
+ const images = await getMediaByIds(item.data.featured_image);
184
+ console.log(images[0]?.url);
185
+ }
186
+ ```
187
+
188
+ ### Filter Operators
189
+
190
+ Available filter operators:
191
+
192
+ - `equals`, `not`
193
+ - `gt`, `gte`, `lt`, `lte`
194
+ - `contains`, `startsWith`, `endsWith`
195
+ - `in`, `notIn`
196
+ - `has`, `hasEvery`, `hasSome`
197
+ - `isNull`
198
+
199
+ ```typescript
200
+ // Complex filtering
201
+ const { data } = await getAllPortfolio({
202
+ filters: {
203
+ AND: {
204
+ "data.category": { equals: "Web Design" },
205
+ "data.title": { contains: "Modern" },
206
+ },
207
+ OR: [{ "data.featured": { equals: true } }, { "data.order": { lt: 5 } }],
208
+ },
209
+ });
210
+ ```
211
+
212
+ ## Static Sites (Vanilla JS)
213
+
214
+ For static sites, use ES modules:
215
+
216
+ ```html
217
+ <!DOCTYPE html>
218
+ <html>
219
+ <head>
220
+ <title>My Site</title>
221
+ </head>
222
+ <body>
223
+ <div id="app"></div>
224
+
225
+ <script type="module">
226
+ import { getAllPortfolio } from "./siteon/index.js";
227
+
228
+ const { data } = await getAllPortfolio();
229
+
230
+ const app = document.getElementById("app");
231
+ app.innerHTML = data
232
+ .map(
233
+ (item) => `
234
+ <div class="portfolio-item">
235
+ <h2>${item.data.title}</h2>
236
+ </div>
237
+ `,
238
+ )
239
+ .join("");
240
+ </script>
241
+ </body>
242
+ </html>
243
+ ```
244
+
245
+ ## Configuration
246
+
247
+ The `siteon.config.json` file stores your configuration:
248
+
249
+ ```json
250
+ {
251
+ "workspaceId": "your-workspace-id",
252
+ "baseUrl": "https://api.compitcom.in",
253
+ "outputDir": "src",
254
+ "projectType": "framework",
255
+ "language": "typescript",
256
+ "httpClient": "fetch",
257
+ "framework": "next",
258
+ "envVarLocation": "env",
259
+ "forms": ["portfolio", "blog-post"],
260
+ "createdAt": "2024-01-01T00:00:00.000Z",
261
+ "updatedAt": "2024-01-01T00:00:00.000Z"
262
+ }
263
+ ```
264
+
265
+ ## Environment Variables
266
+
267
+ If you chose to use environment variables, they are stored in `.env`:
268
+
269
+ ```env
270
+ # Next.js
271
+ NEXT_PUBLIC_SITEON_BASE_URL=https://api.compitcom.in
272
+ NEXT_PUBLIC_SITEON_WORKSPACE_ID=your-workspace-id
273
+
274
+ # Vite/Vue
275
+ VITE_SITEON_BASE_URL=https://api.compitcom.in
276
+ VITE_SITEON_WORKSPACE_ID=your-workspace-id
277
+
278
+ # React (CRA)
279
+ REACT_APP_SITEON_BASE_URL=https://api.compitcom.in
280
+ REACT_APP_SITEON_WORKSPACE_ID=your-workspace-id
281
+ ```
282
+
283
+ ## Field Type Mapping
284
+
285
+ | Form Field Type | TypeScript Type |
286
+ | ------------------------------------ | ------------------------------------------- |
287
+ | text, email, textarea, url, richtext | `string` |
288
+ | date, time, datetime | `string` |
289
+ | int, float | `number` |
290
+ | select, radio | Union of options |
291
+ | checkbox | Array of options |
292
+ | media, image, video | `string[]` |
293
+ | relation (single) | `string \| null` (ID) or `ResolvedRelation` |
294
+ | relation (array) | `string[]` (IDs) or `ResolvedRelation[]` |
295
+ | repeator | `{ value: T }[]` |
296
+
297
+ ## Development
298
+
299
+ ```bash
300
+ # Install dependencies
301
+ bun install
302
+
303
+ # Build
304
+ bun run build
305
+
306
+ # Watch mode
307
+ bun run dev
308
+ ```
309
+
310
+ ## License
311
+
312
+ Private - Compitcom
package/bun.lock ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "lockfileVersion": 1,
3
+ "workspaces": {
4
+ "": {
5
+ "name": "siteon",
6
+ "dependencies": {
7
+ "chalk": "^5.3.0",
8
+ "commander": "^12.1.0",
9
+ "enquirer": "^2.4.1",
10
+ "ora": "^8.0.1",
11
+ },
12
+ "devDependencies": {
13
+ "@types/bun": "^1.1.0",
14
+ "@types/node": "^20.11.0",
15
+ "typescript": "^5.3.3",
16
+ },
17
+ },
18
+ },
19
+ "packages": {
20
+ "@types/bun": ["@types/bun@1.3.6", "", { "dependencies": { "bun-types": "1.3.6" } }, "sha512-uWCv6FO/8LcpREhenN1d1b6fcspAB+cefwD7uti8C8VffIv0Um08TKMn98FynpTiU38+y2dUO55T11NgDt8VAA=="],
21
+
22
+ "@types/node": ["@types/node@20.19.30", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g=="],
23
+
24
+ "ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="],
25
+
26
+ "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
27
+
28
+ "bun-types": ["bun-types@1.3.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ=="],
29
+
30
+ "chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
31
+
32
+ "cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="],
33
+
34
+ "cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="],
35
+
36
+ "commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="],
37
+
38
+ "emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="],
39
+
40
+ "enquirer": ["enquirer@2.4.1", "", { "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" } }, "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ=="],
41
+
42
+ "get-east-asian-width": ["get-east-asian-width@1.4.0", "", {}, "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q=="],
43
+
44
+ "is-interactive": ["is-interactive@2.0.0", "", {}, "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ=="],
45
+
46
+ "is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="],
47
+
48
+ "log-symbols": ["log-symbols@6.0.0", "", { "dependencies": { "chalk": "^5.3.0", "is-unicode-supported": "^1.3.0" } }, "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw=="],
49
+
50
+ "mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="],
51
+
52
+ "onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="],
53
+
54
+ "ora": ["ora@8.2.0", "", { "dependencies": { "chalk": "^5.3.0", "cli-cursor": "^5.0.0", "cli-spinners": "^2.9.2", "is-interactive": "^2.0.0", "is-unicode-supported": "^2.0.0", "log-symbols": "^6.0.0", "stdin-discarder": "^0.2.2", "string-width": "^7.2.0", "strip-ansi": "^7.1.0" } }, "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw=="],
55
+
56
+ "restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="],
57
+
58
+ "signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
59
+
60
+ "stdin-discarder": ["stdin-discarder@0.2.2", "", {}, "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ=="],
61
+
62
+ "string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
63
+
64
+ "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
65
+
66
+ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
67
+
68
+ "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
69
+
70
+ "log-symbols/is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="],
71
+
72
+ "ora/strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="],
73
+
74
+ "string-width/strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="],
75
+
76
+ "ora/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
77
+
78
+ "string-width/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
79
+ }
80
+ }
package/dist/Readme.md ADDED
@@ -0,0 +1,112 @@
1
+ # SiteOn
2
+
3
+ A powerful code generation tool that automatically generates content fetching and form submission code for your workspace.
4
+
5
+ ## What is SiteOn?
6
+
7
+ SiteOn streamlines your development workflow by analyzing your workspace configuration and generating ready-to-use code for:
8
+
9
+ - **Content Fetching**: Automatically generate API calls and data fetching logic based on your workspace structure
10
+ - **Form Submissions**: Create public form submission handlers with proper validation and error handling
11
+
12
+ No more boilerplate code – SiteOn does the heavy lifting for you.
13
+
14
+ ## Installation
15
+
16
+ ### Quick Start with npx (Recommended)
17
+
18
+ Run SiteOn without installing:
19
+
20
+ ```bash
21
+ npx siteon
22
+ ```
23
+
24
+ ```bash
25
+ pnpm dlx siteon
26
+ ```
27
+
28
+ ```bash
29
+ bunx siteon
30
+ ```
31
+
32
+ ### Global Installation
33
+
34
+ Install globally for repeated use:
35
+
36
+ ```bash
37
+ npm install -g siteon
38
+ ```
39
+
40
+ Then run:
41
+
42
+ ```bash
43
+ siteon
44
+ ```
45
+
46
+ ## Usage
47
+
48
+ 1. Navigate to your project directory
49
+ 2. Run the command:
50
+ ```bash
51
+ npx siteon
52
+ ```
53
+ 3. SiteOn will:
54
+ - Analyze your workspace configuration
55
+ - Detect your content structure
56
+ - Generate appropriate code files
57
+ - Set up form submission endpoints
58
+
59
+ ## Features
60
+
61
+ ✨ **Automatic Code Generation** - Generates production-ready code based on your workspace
62
+
63
+ 🔍 **Workspace Detection** - Intelligently analyzes your project structure
64
+
65
+ 📝 **Form Handlers** - Creates public form submission code with validation
66
+
67
+ 🚀 **Zero Configuration** - Works out of the box with sensible defaults
68
+
69
+ ⚡ **Fast & Lightweight** - Minimal dependencies, maximum efficiency
70
+
71
+ ## Generated Code
72
+
73
+ SiteOn generates:
74
+
75
+ - Content fetching functions and API clients
76
+ - Form submission handlers with validation
77
+ - Type definitions (if applicable)
78
+ - Configuration files for your workspace
79
+
80
+ ## Examples
81
+
82
+ ### Basic Usage
83
+
84
+ ```bash
85
+ # In your project directory
86
+ npx siteon
87
+ ```
88
+
89
+ ## How It Works
90
+
91
+ 1. **Workspace Analysis**: SiteOn scans your workspace for content types, schemas, and configurations
92
+ 2. **Code Generation**: Based on the analysis, it generates optimized code tailored to your needs
93
+ 3. **File Output**: Generated code is saved to your project with clear organization
94
+
95
+ ## License
96
+
97
+ MIT
98
+
99
+ ## Support
100
+
101
+ If you encounter any issues or have questions:
102
+
103
+ - Open an issue on [GitHub](https://github.com/yourusername/siteon)
104
+ - Check the [documentation](https://github.com/yourusername/siteon#readme)
105
+
106
+ ## Author
107
+
108
+ Created with ❤️ by the SiteOn team
109
+
110
+ ---
111
+
112
+ **Happy Coding!** 🎉