@avocadostudio-ai/site-sdk 0.1.0 → 0.2.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 (45) hide show
  1. package/README.md +212 -2
  2. package/dist/create-site-page.d.ts +38 -8
  3. package/dist/create-site-page.js +59 -8
  4. package/dist/draft-common.d.ts +32 -0
  5. package/dist/draft-common.js +58 -0
  6. package/dist/draft-context-core.js +39 -6
  7. package/dist/draft-context-core.test.d.ts +10 -0
  8. package/dist/draft-context-core.test.js +146 -0
  9. package/dist/editor-cors.d.ts +12 -0
  10. package/dist/editor-cors.js +31 -6
  11. package/dist/editor-cors.test.d.ts +1 -0
  12. package/dist/editor-cors.test.js +66 -0
  13. package/dist/editor-manifest.d.ts +2 -3
  14. package/dist/editor-manifest.js +12 -64
  15. package/dist/editor-matcher.d.ts +27 -0
  16. package/dist/editor-matcher.js +34 -0
  17. package/dist/editor-query.js +7 -1
  18. package/dist/index.d.ts +2 -0
  19. package/dist/index.js +2 -0
  20. package/dist/integration-check.js +11 -1
  21. package/dist/manifest-utils.d.ts +13 -0
  22. package/dist/manifest-utils.js +30 -3
  23. package/dist/manifest-utils.test.d.ts +1 -0
  24. package/dist/manifest-utils.test.js +72 -0
  25. package/dist/middleware.d.ts +21 -19
  26. package/dist/middleware.js +19 -22
  27. package/dist/next-config.test.d.ts +1 -0
  28. package/dist/next-config.test.js +253 -0
  29. package/dist/page-metadata.d.ts +66 -0
  30. package/dist/page-metadata.js +110 -0
  31. package/dist/page-metadata.test.d.ts +1 -0
  32. package/dist/page-metadata.test.js +105 -0
  33. package/dist/proxy.d.ts +58 -0
  34. package/dist/proxy.js +50 -0
  35. package/dist/proxy.test.d.ts +1 -0
  36. package/dist/proxy.test.js +72 -0
  37. package/dist/publish/field-diff.d.ts +191 -0
  38. package/dist/publish/field-diff.js +252 -0
  39. package/dist/publish/field-diff.test.d.ts +1 -0
  40. package/dist/publish/field-diff.test.js +286 -0
  41. package/dist/server/orchestrator.d.ts +1 -117
  42. package/dist/server/orchestrator.js +14 -733
  43. package/next-config.d.ts +68 -0
  44. package/next-config.mjs +358 -0
  45. package/package.json +63 -19
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Types for `next-config.mjs`.
3
+ *
4
+ * The implementation is plain ESM on purpose — it is imported by `next.config`,
5
+ * before any of Next's loaders exist — so its types cannot be inferred and have
6
+ * to be declared here. A `next.config.ts` under `noImplicitAny` fails without
7
+ * this file.
8
+ */
9
+
10
+ /** The linked Avocado packages that still ship TypeScript entry points. */
11
+ export function linkedAvocadoPackages(from?: string): string[]
12
+
13
+ /** A `next/image` remote pattern, structurally matching Next's own type. */
14
+ export type AvocadoImagePattern = {
15
+ protocol: "http" | "https"
16
+ hostname: string
17
+ port?: string
18
+ pathname?: string
19
+ }
20
+
21
+ /**
22
+ * The image hosts Avocado itself can produce URLs for — stock search, the image
23
+ * models' blob storage, and the placeholder host. `withAvocado` merges these
24
+ * into `images.remotePatterns`; exported so an app that opts out with
25
+ * `{ images: false }` can still reference the list.
26
+ */
27
+ export const AVOCADO_IMAGE_HOSTS: AvocadoImagePattern[]
28
+
29
+ /**
30
+ * The packages that must stay external to the server build — native binaries
31
+ * (`better-sqlite3`, `sharp`) and the provider SDKs `orchestrator-core` reaches
32
+ * through `await import(...)`. `withAvocado` applies these; exported so an app
33
+ * that opts out with `{ serverExternals: false }` can still reference the list.
34
+ */
35
+ export const AVOCADO_SERVER_EXTERNALS: string[]
36
+
37
+ /**
38
+ * Wrap a Next config so `transpilePackages` covers every linked Avocado package,
39
+ * `images.remotePatterns` covers every host Avocado can serve an image from, and
40
+ * Avocado's native and provider dependencies stay external to the server build.
41
+ * Additive, and never throws.
42
+ */
43
+ export function withAvocado<
44
+ T extends {
45
+ transpilePackages?: string[]
46
+ images?: { remotePatterns?: unknown[] }
47
+ serverExternalPackages?: string[]
48
+ /** `null` is in Next's own type for this field, so the constraint admits it. */
49
+ webpack?: ((config: any, context: any) => any) | null
50
+ }
51
+ >(
52
+ config?: T,
53
+ options?: {
54
+ cwd?: string
55
+ silent?: boolean
56
+ /** Set false to manage `images.remotePatterns` yourself. Defaults to true. */
57
+ images?: boolean
58
+ /**
59
+ * Set false to manage `serverExternalPackages` and the server `externals`
60
+ * yourself. Defaults to true.
61
+ */
62
+ serverExternals?: boolean
63
+ /** Environment to read the orchestrator origin from. Defaults to `process.env`. */
64
+ env?: Record<string, string | undefined>
65
+ }
66
+ ): T
67
+
68
+ export default withAvocado
@@ -0,0 +1,358 @@
1
+ /**
2
+ * Next.js config helper.
3
+ *
4
+ * Plain ESM, deliberately: it is imported *by* `next.config`, which Next loads
5
+ * before any of its own loaders exist. Everything else in this package ships
6
+ * TypeScript source in a workspace checkout, and a config that imported that
7
+ * would fail to parse — which is the very failure this file exists to prevent.
8
+ *
9
+ * ## What it prevents
10
+ *
11
+ * Avocado's packages point `main` at `src/index.ts` so a monorepo checkout
12
+ * needs no build step. Webpack has no idea what to do with that, so every
13
+ * linked package must be named in `transpilePackages` — and when one is
14
+ * missing, the error names a file inside `node_modules` and says nothing about
15
+ * the config the integrator has to change:
16
+ *
17
+ * Module parse failed: Unexpected token (27:7)
18
+ * > type InlineToken,
19
+ *
20
+ * Nothing catches it earlier. A type-check does not compile a Next app, and a
21
+ * test suite does not boot one, so the app is green everywhere except in a
22
+ * browser. It also breaks *retroactively*: adding a package to Avocado, or
23
+ * re-exporting one from another, silently breaks every consumer that pinned the
24
+ * old list by hand.
25
+ *
26
+ * So the list is not maintained by hand. This reads what is actually linked and
27
+ * adds whatever ships TypeScript, keeping anything the app already declared.
28
+ *
29
+ * ## What else it prevents
30
+ *
31
+ * Avocado writes image URLs its host never chose. A generated image comes back
32
+ * from Unsplash or from an image model's blob storage, and `next/image` refuses
33
+ * any host not listed in `images.remotePatterns` — so the first image a user
34
+ * generates 500s, on a config line nothing in the integration docs mentioned.
35
+ * Four apps in this repo carried the same hand-copied host list to work around
36
+ * that. It belongs here, next to the other thing an integrator cannot be
37
+ * expected to know.
38
+ *
39
+ * ## And the third thing
40
+ *
41
+ * `orchestrator-core` reaches native binaries (`better-sqlite3`, `sharp`) and
42
+ * heavyweight provider SDKs, some of them through `await import(...)` because
43
+ * they are optional peers. A bundler must be told to leave all of them alone:
44
+ *
45
+ * - A native `.node` binary that gets bundled crashes when it is loaded, not
46
+ * when it is built, so the failure surfaces on the first request.
47
+ * - Turbopack statically resolves dynamic imports, so an optional peer that is
48
+ * *deliberately absent* fails the build with `Module not found`. "An optional
49
+ * peer is genuinely skipped" holds at install time; it does not hold at bundle
50
+ * time.
51
+ *
52
+ * `serverExternalPackages` alone is not enough, and this is the part nobody
53
+ * guesses: `transpilePackages` overrides server externals for a transitive
54
+ * dependency, so `sharp` reached through the transpiled `orchestrator-core` got
55
+ * bundled anyway. The two options interact, this helper sets both, and it is the
56
+ * only place that knows it has to.
57
+ */
58
+
59
+ import { existsSync, readdirSync, readFileSync } from "node:fs"
60
+ import { dirname, join, resolve } from "node:path"
61
+
62
+ /** Scopes whose packages may ship TypeScript source in a linked checkout. */
63
+ const SCOPES = ["@avocadostudio-ai", "@ai-site-editor"]
64
+
65
+ function readJson(file) {
66
+ try {
67
+ return JSON.parse(readFileSync(file, "utf8"))
68
+ } catch {
69
+ return null
70
+ }
71
+ }
72
+
73
+ /** Does any entry point in this manifest resolve to TypeScript? */
74
+ function shipsTypeScript(pkg) {
75
+ const seen = []
76
+ const walk = (value) => {
77
+ if (typeof value === "string") seen.push(value)
78
+ else if (value && typeof value === "object") Object.values(value).forEach(walk)
79
+ }
80
+ walk(pkg.main)
81
+ walk(pkg.types)
82
+ walk(pkg.exports)
83
+ return seen.some((entry) => /\.tsx?$/.test(entry))
84
+ }
85
+
86
+ /** Every `node_modules` directory from `start` up to the filesystem root. */
87
+ function nodeModulesDirs(start) {
88
+ const dirs = []
89
+ let current = resolve(start)
90
+ for (;;) {
91
+ const candidate = join(current, "node_modules")
92
+ if (existsSync(candidate)) dirs.push(candidate)
93
+ const parent = dirname(current)
94
+ if (parent === current) return dirs
95
+ current = parent
96
+ }
97
+ }
98
+
99
+ /**
100
+ * The linked Avocado packages that have to be transpiled with the app.
101
+ *
102
+ * Resolved from what is on disk rather than from a list in this file, so a
103
+ * package added to Avocado tomorrow is picked up without anyone editing a
104
+ * config. A package installed from a registry resolves to built JavaScript and
105
+ * is correctly left out.
106
+ */
107
+ export function linkedAvocadoPackages(from = process.cwd()) {
108
+ const found = new Set()
109
+ for (const nodeModules of nodeModulesDirs(from)) {
110
+ for (const scope of SCOPES) {
111
+ const scopeDir = join(nodeModules, scope)
112
+ if (!existsSync(scopeDir)) continue
113
+ let entries
114
+ try {
115
+ entries = readdirSync(scopeDir)
116
+ } catch {
117
+ continue
118
+ }
119
+ for (const name of entries) {
120
+ const full = `${scope}/${name}`
121
+ if (found.has(full)) continue
122
+ const pkg = readJson(join(scopeDir, name, "package.json"))
123
+ if (pkg && shipsTypeScript(pkg)) found.add(full)
124
+ }
125
+ }
126
+ }
127
+ return [...found].sort()
128
+ }
129
+
130
+ /**
131
+ * Hosts Avocado itself can put in an image URL.
132
+ *
133
+ * Unsplash for stock search, the image models' own blob storage for generated
134
+ * images, `placehold.co` for the placeholder a block renders before an image is
135
+ * chosen. A host the *site's own CMS* serves from (`cdn.sanity.io`,
136
+ * `images.ctfassets.net`, …) is not here — that is the app's to declare,
137
+ * because only the app knows which CMS it uses.
138
+ */
139
+ export const AVOCADO_IMAGE_HOSTS = [
140
+ { protocol: "https", hostname: "images.unsplash.com" },
141
+ { protocol: "https", hostname: "plus.unsplash.com" },
142
+ { protocol: "https", hostname: "oaidalleapiprodscus.blob.core.windows.net" },
143
+ { protocol: "https", hostname: "generativelanguage.googleapis.com" },
144
+ { protocol: "https", hostname: "placehold.co" },
145
+ ]
146
+
147
+ /** `{protocol}://{hostname}` — the identity two patterns are deduped on. */
148
+ function patternKey(pattern) {
149
+ return `${pattern.protocol ?? "https"}://${pattern.hostname}${pattern.port ? `:${pattern.port}` : ""}${pattern.pathname ?? ""}`
150
+ }
151
+
152
+ /**
153
+ * The orchestrator's own origin, when it is somewhere `next/image` would need
154
+ * permission to reach.
155
+ *
156
+ * Uploaded and locally-cached images are served by the orchestrator, so its
157
+ * host has to be allowed too — and unlike the list above it is per-deployment,
158
+ * which is exactly why hand-maintained config kept getting it wrong.
159
+ */
160
+ function orchestratorImagePattern(env) {
161
+ const configured = (env.NEXT_PUBLIC_ORCHESTRATOR_URL ?? env.ORCHESTRATOR_URL ?? "").trim()
162
+ /*
163
+ * The same default `draft-fetch.ts` uses — but only outside production. A
164
+ * build that never names its orchestrator is a local one, and allowing
165
+ * `localhost` through the image optimizer of a deployed site is a wider hole
166
+ * than the convenience is worth.
167
+ */
168
+ const raw = configured || (env.NODE_ENV === "production" ? "" : "http://localhost:4200")
169
+ if (!raw) return null
170
+ try {
171
+ const url = new URL(raw)
172
+ if (url.protocol !== "http:" && url.protocol !== "https:") return null
173
+ return {
174
+ protocol: url.protocol.replace(":", ""),
175
+ hostname: url.hostname,
176
+ ...(url.port ? { port: url.port } : {}),
177
+ }
178
+ } catch {
179
+ return null
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Merge Avocado's image hosts into a Next config's `images.remotePatterns`.
185
+ *
186
+ * Additive, like the transpile list: whatever the app declared stays, in its
187
+ * own order, and a host it already covers is not duplicated.
188
+ */
189
+ function withAvocadoImages(config, env) {
190
+ const images = config.images ?? {}
191
+ const declared = Array.isArray(images.remotePatterns) ? images.remotePatterns : []
192
+ const seen = new Set(declared.map(patternKey))
193
+
194
+ const additions = []
195
+ for (const pattern of [...AVOCADO_IMAGE_HOSTS, orchestratorImagePattern(env)]) {
196
+ if (!pattern) continue
197
+ const key = patternKey(pattern)
198
+ if (seen.has(key)) continue
199
+ seen.add(key)
200
+ additions.push(pattern)
201
+ }
202
+ if (additions.length === 0) return config
203
+
204
+ return { ...config, images: { ...images, remotePatterns: [...declared, ...additions] } }
205
+ }
206
+
207
+ /**
208
+ * Packages a bundler must not bundle into the server build.
209
+ *
210
+ * Two kinds, and they fail differently:
211
+ *
212
+ * - **Native binaries** — `better-sqlite3` (the orchestrator's state) and
213
+ * `sharp` (image processing). Bundling one produces a build that succeeds and
214
+ * a server that dies loading the `.node` file.
215
+ * - **Provider SDKs** — reached from `orchestrator-core`, several of them via
216
+ * `await import(...)` so that a site which does not use a provider need not
217
+ * install it. Turbopack resolves those statically and fails the build over a
218
+ * package that was never meant to be there.
219
+ *
220
+ * Naming a package that is not installed is a no-op, which is what makes one
221
+ * list correct for every consumer: a site with no Gemini key still lists
222
+ * `@google/genai`, and nothing looks for it.
223
+ */
224
+ export const AVOCADO_SERVER_EXTERNALS = [
225
+ "better-sqlite3",
226
+ "sharp",
227
+ "@anthropic-ai/sdk",
228
+ "@anthropic-ai/claude-agent-sdk",
229
+ "openai",
230
+ "@google/genai",
231
+ "googleapis",
232
+ "@modelcontextprotocol/sdk",
233
+ ]
234
+
235
+ /**
236
+ * Mark every entry in `AVOCADO_SERVER_EXTERNALS` external to the server build,
237
+ * both ways it has to be said.
238
+ *
239
+ * `serverExternalPackages` is the documented knob and is not sufficient on its
240
+ * own: `transpilePackages` — which the same helper is busy populating — takes
241
+ * precedence for a *transitive* dependency, so a native binary imported by a
242
+ * transpiled Avocado package is bundled despite being listed. The webpack
243
+ * `externals` entry is what actually holds, and it is scoped to `isServer` so a
244
+ * client bundle is untouched.
245
+ *
246
+ * Both halves are additive: an app's own externals and its own `webpack` hook
247
+ * run first and keep whatever they did.
248
+ *
249
+ * The hook is attached even for an app that had none, which has one cosmetic
250
+ * cost: Next warns "Webpack is configured while Turbopack is not" for a
251
+ * Turbopack app that declares no `turbopack` key of its own. Under Turbopack the
252
+ * hook is never called and `serverExternalPackages` is what carries the fix, so
253
+ * the warning is about an inert function. An app that would rather not see it
254
+ * can declare `turbopack: {}` or opt out with `{ serverExternals: false }`.
255
+ */
256
+ function withAvocadoServerExternals(config) {
257
+ const declared = Array.isArray(config.serverExternalPackages) ? config.serverExternalPackages : []
258
+ const missing = AVOCADO_SERVER_EXTERNALS.filter((name) => !declared.includes(name))
259
+
260
+ const appWebpack = typeof config.webpack === "function" ? config.webpack : null
261
+
262
+ return {
263
+ ...config,
264
+ ...(missing.length > 0 ? { serverExternalPackages: [...declared, ...missing] } : {}),
265
+ webpack(webpackConfig, context) {
266
+ const result = appWebpack ? appWebpack(webpackConfig, context) : webpackConfig
267
+ if (!context?.isServer) return result
268
+
269
+ const existing = result.externals ?? []
270
+ result.externals = [
271
+ ...(Array.isArray(existing) ? existing : [existing]),
272
+ /*
273
+ * A function rather than a name list so that a deep import
274
+ * (`sharp/lib/...`) is externalised along with the package root.
275
+ * Calling back with no arguments means "not external" and hands the
276
+ * request to the next resolver, which is why this composes.
277
+ */
278
+ ({ request }, callback) => {
279
+ if (!request) return callback()
280
+ for (const name of AVOCADO_SERVER_EXTERNALS) {
281
+ if (request === name || request.startsWith(`${name}/`)) {
282
+ return callback(null, `commonjs ${request}`)
283
+ }
284
+ }
285
+ callback()
286
+ },
287
+ ]
288
+ return result
289
+ },
290
+ }
291
+ }
292
+
293
+ /**
294
+ * Wrap a Next config so its `transpilePackages` covers every linked Avocado
295
+ * package.
296
+ *
297
+ * Also merges Avocado's own image hosts into `images.remotePatterns`, since a
298
+ * generated image comes from a host the site never chose, and marks Avocado's
299
+ * native and provider dependencies external to the server build, since neither
300
+ * survives being bundled. Pass `{ images: false }` or
301
+ * `{ serverExternals: false }` to manage either list yourself.
302
+ *
303
+ * Additive and total: whatever the app already listed is kept in the order it
304
+ * wrote it, unrelated entries included, its own `webpack` hook still runs and
305
+ * still wins, and any failure to read the filesystem leaves the config exactly
306
+ * as it was. Never throws — a helper that can break `next.config` is worse than
307
+ * the bug it fixes.
308
+ */
309
+ export function withAvocado(config = {}, options = {}) {
310
+ const {
311
+ cwd = process.cwd(),
312
+ silent = false,
313
+ images = true,
314
+ serverExternals = true,
315
+ env = process.env,
316
+ } = options
317
+
318
+ /*
319
+ * Applied before the `transpilePackages` derivation below, which has two
320
+ * early returns of its own — a config that already lists every linked package
321
+ * still needs its externals.
322
+ */
323
+ const withImages = images ? withAvocadoImages(config, env) : config
324
+ const result = serverExternals ? withAvocadoServerExternals(withImages) : withImages
325
+
326
+ let linked
327
+ try {
328
+ linked = linkedAvocadoPackages(cwd)
329
+ } catch {
330
+ return result
331
+ }
332
+
333
+ const declared = Array.isArray(result.transpilePackages) ? result.transpilePackages : []
334
+ const missing = linked.filter((name) => !declared.includes(name))
335
+ if (missing.length === 0) return result
336
+
337
+ if (!silent) {
338
+ /*
339
+ * Best-effort only. Next runs `next.config` inside its own reporter, and on
340
+ * Next 16 neither stdout nor stderr written during that window reaches the
341
+ * terminal (measured, not assumed). So this is not the mechanism that keeps
342
+ * an integrator informed — the auto-fix is, and the comment they write next
343
+ * to their own `withAvocado(...)` call is. It stays because it does surface
344
+ * on hosts that do not capture the config run, and it costs nothing.
345
+ */
346
+ try {
347
+ process.stderr.write(
348
+ `[avocado] transpilePackages: added ${missing.join(", ")} — linked from source, so webpack has to compile them.\n`
349
+ )
350
+ } catch {
351
+ // A host with no writable stderr is not a reason to fail the build.
352
+ }
353
+ }
354
+
355
+ return { ...result, transpilePackages: [...declared, ...missing] }
356
+ }
357
+
358
+ export default withAvocado
package/package.json CHANGED
@@ -1,58 +1,94 @@
1
1
  {
2
2
  "name": "@avocadostudio-ai/site-sdk",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {
8
8
  "./package.json": "./package.json",
9
9
  ".": {
10
+ "types": "./dist/index.d.ts",
10
11
  "import": "./dist/index.js",
11
- "types": "./dist/index.d.ts"
12
+ "default": "./dist/index.js"
12
13
  },
13
14
  "./draft": {
15
+ "types": "./dist/draft.d.ts",
14
16
  "import": "./dist/draft.js",
15
- "types": "./dist/draft.d.ts"
17
+ "default": "./dist/draft.js"
16
18
  },
17
19
  "./editor": {
20
+ "types": "./dist/editor.d.ts",
18
21
  "import": "./dist/editor.js",
19
- "types": "./dist/editor.d.ts"
22
+ "default": "./dist/editor.js"
20
23
  },
21
24
  "./routes": {
25
+ "types": "./dist/routes.d.ts",
22
26
  "import": "./dist/routes.js",
23
- "types": "./dist/routes.d.ts"
27
+ "default": "./dist/routes.js"
24
28
  },
25
29
  "./editor-manifest": {
30
+ "types": "./dist/editor-manifest.d.ts",
26
31
  "import": "./dist/editor-manifest.js",
27
- "types": "./dist/editor-manifest.d.ts"
32
+ "default": "./dist/editor-manifest.js"
28
33
  },
29
34
  "./draft/core": {
35
+ "types": "./dist/draft-context-core.d.ts",
30
36
  "import": "./dist/draft-context-core.js",
31
- "types": "./dist/draft-context-core.d.ts"
37
+ "default": "./dist/draft-context-core.js"
32
38
  },
33
39
  "./routes/core": {
40
+ "types": "./dist/draft-routes-core.d.ts",
34
41
  "import": "./dist/draft-routes-core.js",
35
- "types": "./dist/draft-routes-core.d.ts"
42
+ "default": "./dist/draft-routes-core.js"
36
43
  },
37
44
  "./publish-handlers/json-file": {
45
+ "types": "./dist/publish-handlers/json-file.d.ts",
38
46
  "import": "./dist/publish-handlers/json-file.js",
39
- "types": "./dist/publish-handlers/json-file.d.ts"
47
+ "default": "./dist/publish-handlers/json-file.js"
48
+ },
49
+ "./publish": {
50
+ "types": "./dist/publish/field-diff.d.ts",
51
+ "import": "./dist/publish/field-diff.js",
52
+ "default": "./dist/publish/field-diff.js"
40
53
  },
41
54
  "./middleware": {
55
+ "types": "./dist/middleware.d.ts",
42
56
  "import": "./dist/middleware.js",
43
- "types": "./dist/middleware.d.ts"
57
+ "default": "./dist/middleware.js"
58
+ },
59
+ "./proxy": {
60
+ "types": "./dist/proxy.d.ts",
61
+ "import": "./dist/proxy.js",
62
+ "default": "./dist/proxy.js"
63
+ },
64
+ "./matcher": {
65
+ "types": "./dist/editor-matcher.d.ts",
66
+ "import": "./dist/editor-matcher.js",
67
+ "default": "./dist/editor-matcher.js"
44
68
  },
45
69
  "./navigation": {
70
+ "types": "./dist/navigation.d.ts",
46
71
  "import": "./dist/navigation.js",
47
- "types": "./dist/navigation.d.ts"
72
+ "default": "./dist/navigation.js"
48
73
  },
49
74
  "./page": {
75
+ "types": "./dist/create-site-page.d.ts",
50
76
  "import": "./dist/create-site-page.js",
51
- "types": "./dist/create-site-page.d.ts"
77
+ "default": "./dist/create-site-page.js"
78
+ },
79
+ "./seo": {
80
+ "types": "./dist/page-metadata.d.ts",
81
+ "import": "./dist/page-metadata.js",
82
+ "default": "./dist/page-metadata.js"
52
83
  },
53
84
  "./server": {
85
+ "types": "./dist/server/orchestrator.d.ts",
54
86
  "import": "./dist/server/orchestrator.js",
55
- "types": "./dist/server/orchestrator.d.ts"
87
+ "default": "./dist/server/orchestrator.js"
88
+ },
89
+ "./next-config": {
90
+ "types": "./next-config.d.ts",
91
+ "default": "./next-config.mjs"
56
92
  }
57
93
  },
58
94
  "repository": {
@@ -65,27 +101,34 @@
65
101
  "access": "public"
66
102
  },
67
103
  "files": [
68
- "dist"
104
+ "dist",
105
+ "next-config.d.ts",
106
+ "next-config.mjs"
69
107
  ],
70
108
  "dependencies": {
71
109
  "zod": "^4.3.6",
72
- "@avocadostudio-ai/blocks": "0.1.0",
73
- "@avocadostudio-ai/preview-adapter": "0.1.0",
74
- "@avocadostudio-ai/shared": "0.1.0"
110
+ "@avocadostudio-ai/blocks": "0.2.0",
111
+ "@avocadostudio-ai/preview-adapter": "0.2.0",
112
+ "@avocadostudio-ai/shared": "0.2.0"
75
113
  },
76
114
  "peerDependencies": {
77
115
  "next": ">=15.0.0",
78
116
  "react": ">=19.0.0",
79
117
  "react-dom": ">=19.0.0",
80
- "@avocadostudio-ai/orchestrator-core": "^0.1.0"
118
+ "better-sqlite3": ">=12.0.0",
119
+ "@avocadostudio-ai/orchestrator-core": "^0.2.0"
81
120
  },
82
121
  "peerDependenciesMeta": {
83
122
  "@avocadostudio-ai/orchestrator-core": {
84
123
  "optional": true
124
+ },
125
+ "better-sqlite3": {
126
+ "optional": true
85
127
  }
86
128
  },
87
129
  "devDependencies": {
88
130
  "@types/react": "^19.0.10",
131
+ "tsx": "^4.21.0",
89
132
  "typescript": "^5.7.3"
90
133
  },
91
134
  "description": "SDK for adding Avocado Studio AI editing and live preview to a Next.js site",
@@ -96,7 +139,8 @@
96
139
  },
97
140
  "scripts": {
98
141
  "build": "tsc -p tsconfig.build.json",
99
- "typecheck": "tsc --noEmit"
142
+ "typecheck": "tsc --noEmit",
143
+ "test": "NODE_ENV=test node ../../scripts/run-tests.mjs"
100
144
  },
101
145
  "bin": {
102
146
  "avocado-register": "./dist/cli/register.js"