@easybits.cloud/html-tailwind-generator 0.1.1 → 0.1.3

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.
package/README.md CHANGED
@@ -26,16 +26,19 @@ All API keys can be set via environment variables instead of passing them explic
26
26
 
27
27
  | Variable | Used by | Description |
28
28
  |----------|---------|-------------|
29
+ | `OPENAI_API_KEY` | `generateLanding`, `refineLanding`, DALL-E images | OpenAI API key — enables GPT-4o generation + DALL-E 3 images |
29
30
  | `ANTHROPIC_API_KEY` | `generateLanding`, `refineLanding` | Anthropic API key (auto-read by `@ai-sdk/anthropic`) |
30
31
  | `PEXELS_API_KEY` | `enrichImages`, `searchImage` | Pexels stock photo API key |
31
32
 
32
- OpenAI keys must be passed explicitly via `openaiApiKey` there is no env var fallback (to avoid accidentally mixing providers).
33
+ **Priority**: If both `OPENAI_API_KEY` and `ANTHROPIC_API_KEY` are set, OpenAI takes precedence. To force Anthropic, pass `anthropicApiKey` explicitly and omit `openaiApiKey`.
34
+
35
+ **Planned**: Mix providers — use Anthropic for text generation + DALL-E for images (best of both). This is on the roadmap; [open an issue](https://github.com/blissito/easybits/issues) to bump priority.
33
36
 
34
37
  ## Quick Start
35
38
 
36
39
  ### Generate a landing page (server-side)
37
40
 
38
- The simplest usage — just set `ANTHROPIC_API_KEY` and `PEXELS_API_KEY` in your `.env`:
41
+ The simplest usage — set either `OPENAI_API_KEY` or `ANTHROPIC_API_KEY` (plus `PEXELS_API_KEY` for stock photos) in your `.env`:
39
42
 
40
43
  ```ts
41
44
  import { generateLanding } from "@easybits.cloud/html-tailwind-generator/generate";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easybits.cloud/html-tailwind-generator",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "AI-powered landing page generator with Tailwind CSS — canvas editor, streaming generation, and one-click deploy",
5
5
  "license": "PolyForm-Noncommercial-1.0.0",
6
6
  "type": "module",
@@ -34,17 +34,39 @@
34
34
  "react-icons": ">=5"
35
35
  },
36
36
  "peerDependenciesMeta": {
37
- "@codemirror/lang-html": { "optional": true },
38
- "@codemirror/state": { "optional": true },
39
- "@codemirror/theme-one-dark": { "optional": true },
40
- "@codemirror/view": { "optional": true },
41
- "@codemirror/commands": { "optional": true },
42
- "@codemirror/search": { "optional": true },
43
- "@codemirror/language": { "optional": true },
44
- "@codemirror/autocomplete": { "optional": true },
45
- "react-icons": { "optional": true },
46
- "@ai-sdk/openai": { "optional": true },
47
- "react-dom": { "optional": true }
37
+ "@codemirror/lang-html": {
38
+ "optional": true
39
+ },
40
+ "@codemirror/state": {
41
+ "optional": true
42
+ },
43
+ "@codemirror/theme-one-dark": {
44
+ "optional": true
45
+ },
46
+ "@codemirror/view": {
47
+ "optional": true
48
+ },
49
+ "@codemirror/commands": {
50
+ "optional": true
51
+ },
52
+ "@codemirror/search": {
53
+ "optional": true
54
+ },
55
+ "@codemirror/language": {
56
+ "optional": true
57
+ },
58
+ "@codemirror/autocomplete": {
59
+ "optional": true
60
+ },
61
+ "react-icons": {
62
+ "optional": true
63
+ },
64
+ "@ai-sdk/openai": {
65
+ "optional": true
66
+ },
67
+ "react-dom": {
68
+ "optional": true
69
+ }
48
70
  },
49
71
  "dependencies": {
50
72
  "nanoid": "^5.1.5"
package/src/generate.ts CHANGED
@@ -7,9 +7,10 @@ import { generateImage } from "./images/dalleImages";
7
7
  import type { Section3 } from "./types";
8
8
 
9
9
  function resolveModel(opts: { openaiApiKey?: string; anthropicApiKey?: string; modelId?: string; defaultOpenai: string; defaultAnthropic: string }) {
10
- if (opts.openaiApiKey) {
10
+ const openaiKey = opts.openaiApiKey || process.env.OPENAI_API_KEY;
11
+ if (openaiKey) {
11
12
  const { createOpenAI } = require("@ai-sdk/openai");
12
- const openai = createOpenAI({ apiKey: opts.openaiApiKey });
13
+ const openai = createOpenAI({ apiKey: openaiKey });
13
14
  return openai(opts.modelId || opts.defaultOpenai);
14
15
  }
15
16
  const anthropic = opts.anthropicApiKey
@@ -157,7 +158,7 @@ export interface GenerateOptions {
157
158
  export async function generateLanding(options: GenerateOptions): Promise<Section3[]> {
158
159
  const {
159
160
  anthropicApiKey,
160
- openaiApiKey,
161
+ openaiApiKey: _openaiApiKey,
161
162
  prompt,
162
163
  referenceImage,
163
164
  extraInstructions,
@@ -170,6 +171,7 @@ export async function generateLanding(options: GenerateOptions): Promise<Section
170
171
  onError,
171
172
  } = options;
172
173
 
174
+ const openaiApiKey = _openaiApiKey || process.env.OPENAI_API_KEY;
173
175
  const model = resolveModel({ openaiApiKey, anthropicApiKey, modelId, defaultOpenai: "gpt-4o", defaultAnthropic: "claude-sonnet-4-6" });
174
176
 
175
177
  // Build prompt content (supports multimodal with reference image)
package/src/refine.ts CHANGED
@@ -3,9 +3,10 @@ import { createAnthropic } from "@ai-sdk/anthropic";
3
3
  import { enrichImages } from "./images/enrichImages";
4
4
 
5
5
  function resolveModel(opts: { openaiApiKey?: string; anthropicApiKey?: string; modelId?: string; defaultOpenai: string; defaultAnthropic: string }) {
6
- if (opts.openaiApiKey) {
6
+ const openaiKey = opts.openaiApiKey || process.env.OPENAI_API_KEY;
7
+ if (openaiKey) {
7
8
  const { createOpenAI } = require("@ai-sdk/openai");
8
- const openai = createOpenAI({ apiKey: opts.openaiApiKey });
9
+ const openai = createOpenAI({ apiKey: openaiKey });
9
10
  return openai(opts.modelId || opts.defaultOpenai);
10
11
  }
11
12
  const anthropic = opts.anthropicApiKey
@@ -67,7 +68,7 @@ export interface RefineOptions {
67
68
  export async function refineLanding(options: RefineOptions): Promise<string> {
68
69
  const {
69
70
  anthropicApiKey,
70
- openaiApiKey,
71
+ openaiApiKey: _openaiApiKey,
71
72
  currentHtml,
72
73
  instruction,
73
74
  referenceImage,
@@ -79,6 +80,7 @@ export async function refineLanding(options: RefineOptions): Promise<string> {
79
80
  onError,
80
81
  } = options;
81
82
 
83
+ const openaiApiKey = _openaiApiKey || process.env.OPENAI_API_KEY;
82
84
  const defaultOpenai = referenceImage ? "gpt-4o" : "gpt-4o-mini";
83
85
  const defaultAnthropic = referenceImage ? "claude-sonnet-4-6" : "claude-haiku-4-5-20251001";
84
86
  const model = resolveModel({ openaiApiKey, anthropicApiKey, modelId, defaultOpenai, defaultAnthropic });