@vard-app/sdk 0.1.2 → 0.1.4
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 +57 -71
- package/dist/index.d.mts +4 -17
- package/dist/index.d.ts +4 -17
- package/dist/index.js +162 -14
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +160 -13
- package/dist/index.mjs.map +1 -1
- package/dist/next.d.mts +2 -12
- package/dist/next.d.ts +2 -12
- package/dist/next.js +113 -14
- package/dist/next.js.map +1 -1
- package/dist/next.mjs +113 -14
- package/dist/next.mjs.map +1 -1
- package/dist/{types-eJuYa65b.d.mts → types-Dd-I7jwP.d.mts} +93 -7
- package/dist/{types-eJuYa65b.d.ts → types-Dd-I7jwP.d.ts} +93 -7
- package/package.json +2 -2
package/dist/index.mjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
// src/fetch-store.ts
|
|
2
2
|
function createVardFetchStore(options = {}) {
|
|
3
3
|
const {
|
|
4
|
-
apiBase = "https://
|
|
5
|
-
workspaceId = options.workspaceId ?? process.env.VARD_WORKSPACE_ID,
|
|
4
|
+
apiBase = options.apiBase ?? process.env.VARD_API_BASE ?? process.env.NEXT_PUBLIC_VARD_API_BASE ?? "https://dash.vard.app",
|
|
6
5
|
apiKey = options.apiKey ?? process.env.VARD_API_KEY,
|
|
7
6
|
fetchOptions = {}
|
|
8
7
|
} = options;
|
|
9
8
|
let resolvedValues = null;
|
|
9
|
+
let structuredContent = null;
|
|
10
10
|
let fetchPromise = null;
|
|
11
11
|
async function fetchValues() {
|
|
12
12
|
const isDevelopment = process.env.NODE_ENV === "development";
|
|
13
|
-
if (!apiKey
|
|
13
|
+
if (!apiKey) {
|
|
14
14
|
if (!isDevelopment) {
|
|
15
15
|
console.error(
|
|
16
16
|
"\x1B[31m[vard] Missing configuration! VARD_API_KEY is not set.\x1B[0m\nPlease set this environment variable in your production environment."
|
|
@@ -20,38 +20,51 @@ function createVardFetchStore(options = {}) {
|
|
|
20
20
|
"[vard] No API Key found. Running in local fallback mode (using default values)."
|
|
21
21
|
);
|
|
22
22
|
}
|
|
23
|
-
return /* @__PURE__ */ new Map();
|
|
23
|
+
return { variables: /* @__PURE__ */ new Map(), structured: {} };
|
|
24
24
|
}
|
|
25
|
-
const url =
|
|
25
|
+
const url = `${apiBase}/api/content/variables?structured=true`;
|
|
26
26
|
try {
|
|
27
27
|
const res = await fetch(url, {
|
|
28
28
|
...fetchOptions,
|
|
29
29
|
headers: {
|
|
30
30
|
...fetchOptions.headers,
|
|
31
|
-
|
|
31
|
+
"X-Vard-API-Key": apiKey
|
|
32
32
|
}
|
|
33
33
|
});
|
|
34
34
|
if (!res.ok) {
|
|
35
35
|
console.warn(`[vard] Failed to fetch variables: ${res.status}`);
|
|
36
|
-
return /* @__PURE__ */ new Map();
|
|
36
|
+
return { variables: /* @__PURE__ */ new Map(), structured: {} };
|
|
37
37
|
}
|
|
38
38
|
const data = await res.json();
|
|
39
|
-
|
|
39
|
+
if (Array.isArray(data)) {
|
|
40
|
+
return {
|
|
41
|
+
variables: new Map(data.map((v2) => [v2.key, v2.value])),
|
|
42
|
+
structured: {}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
variables: new Map(data.variables.map((v2) => [v2.key, v2.value])),
|
|
47
|
+
structured: data.structured || {}
|
|
48
|
+
};
|
|
40
49
|
} catch (err) {
|
|
41
|
-
|
|
42
|
-
return /* @__PURE__ */ new Map();
|
|
50
|
+
return { variables: /* @__PURE__ */ new Map(), structured: {} };
|
|
43
51
|
}
|
|
44
52
|
}
|
|
45
53
|
return {
|
|
46
54
|
get(key) {
|
|
47
55
|
return resolvedValues?.get(key);
|
|
48
56
|
},
|
|
57
|
+
getStructured() {
|
|
58
|
+
return structuredContent;
|
|
59
|
+
},
|
|
49
60
|
async prefetch() {
|
|
50
61
|
if (resolvedValues) return;
|
|
51
62
|
if (!fetchPromise) {
|
|
52
63
|
fetchPromise = fetchValues();
|
|
53
64
|
}
|
|
54
|
-
|
|
65
|
+
const result = await fetchPromise;
|
|
66
|
+
resolvedValues = result.variables;
|
|
67
|
+
structuredContent = result.structured;
|
|
55
68
|
}
|
|
56
69
|
};
|
|
57
70
|
}
|
|
@@ -70,7 +83,7 @@ var noopStore = {
|
|
|
70
83
|
}
|
|
71
84
|
};
|
|
72
85
|
function createVard(options = {}) {
|
|
73
|
-
const store = options.store ?? (options.apiKey
|
|
86
|
+
const store = options.store ?? (options.apiKey ? createVardFetchStore(options) : noopStore);
|
|
74
87
|
const registry = [];
|
|
75
88
|
function register(def) {
|
|
76
89
|
if (!registry.find((d) => d.key === def.key)) {
|
|
@@ -82,7 +95,85 @@ function createVard(options = {}) {
|
|
|
82
95
|
}
|
|
83
96
|
return def.defaultValue;
|
|
84
97
|
}
|
|
98
|
+
function flattenSchema(schema, prefix = "") {
|
|
99
|
+
const result = {};
|
|
100
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
101
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
102
|
+
if (typeof value === "object" && value !== null && "type" in value) {
|
|
103
|
+
const field = value;
|
|
104
|
+
if (field.type === "collection") {
|
|
105
|
+
const collection = field;
|
|
106
|
+
const listItemSchema = {};
|
|
107
|
+
for (const [fKey, fVal] of Object.entries(collection.schema)) {
|
|
108
|
+
listItemSchema[fKey] = fVal.type;
|
|
109
|
+
}
|
|
110
|
+
register({
|
|
111
|
+
key: fullKey,
|
|
112
|
+
label: labelFromKey(key),
|
|
113
|
+
type: "list",
|
|
114
|
+
defaultValue: [],
|
|
115
|
+
editableBy: "member",
|
|
116
|
+
listItemSchema,
|
|
117
|
+
isCollection: true
|
|
118
|
+
});
|
|
119
|
+
Object.defineProperty(result, key, {
|
|
120
|
+
get: () => store.get(fullKey) ?? [],
|
|
121
|
+
enumerable: true
|
|
122
|
+
});
|
|
123
|
+
} else {
|
|
124
|
+
const vardField = field;
|
|
125
|
+
register({
|
|
126
|
+
key: fullKey,
|
|
127
|
+
label: vardField.label ?? labelFromKey(key),
|
|
128
|
+
description: vardField.description,
|
|
129
|
+
type: vardField.type,
|
|
130
|
+
defaultValue: vardField.default,
|
|
131
|
+
editableBy: vardField.editableBy ?? "member",
|
|
132
|
+
group: vardField.group
|
|
133
|
+
});
|
|
134
|
+
Object.defineProperty(result, key, {
|
|
135
|
+
get: () => store.get(fullKey) ?? vardField.default,
|
|
136
|
+
enumerable: true
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
} else if (typeof value === "object" && value !== null) {
|
|
140
|
+
result[key] = flattenSchema(value, fullKey);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
if (options.schema && process.env.NODE_ENV === "development" && options.apiKey) {
|
|
146
|
+
flattenSchema(options.schema);
|
|
147
|
+
const definitions = [...registry];
|
|
148
|
+
const apiBase = process.env.VARD_API_BASE ?? process.env.NEXT_PUBLIC_VARD_API_BASE ?? "https://dash.vard.app";
|
|
149
|
+
fetch(`${apiBase}/api/content/variables/sync`, {
|
|
150
|
+
method: "POST",
|
|
151
|
+
headers: {
|
|
152
|
+
"Content-Type": "application/json",
|
|
153
|
+
"X-Vard-API-Key": options.apiKey
|
|
154
|
+
},
|
|
155
|
+
body: JSON.stringify({
|
|
156
|
+
definitions,
|
|
157
|
+
schema: options.schema
|
|
158
|
+
})
|
|
159
|
+
}).catch((err) => console.warn("[vard] Auto-sync failed:", err));
|
|
160
|
+
}
|
|
85
161
|
const client = {
|
|
162
|
+
define(schema) {
|
|
163
|
+
return flattenSchema(schema);
|
|
164
|
+
},
|
|
165
|
+
async get() {
|
|
166
|
+
if (store.prefetch) {
|
|
167
|
+
await store.prefetch();
|
|
168
|
+
}
|
|
169
|
+
if (store.getStructured) {
|
|
170
|
+
const structured = store.getStructured();
|
|
171
|
+
if (structured && Object.keys(structured).length > 0) {
|
|
172
|
+
return structured;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return flattenSchema(options.schema ?? {});
|
|
176
|
+
},
|
|
86
177
|
string(key, fallback, opts = {}) {
|
|
87
178
|
return register({
|
|
88
179
|
key,
|
|
@@ -183,6 +274,14 @@ function createVard(options = {}) {
|
|
|
183
274
|
return client.list(key, schema, fallback, { ...opts, group: "Global" });
|
|
184
275
|
}
|
|
185
276
|
},
|
|
277
|
+
extend(fragment) {
|
|
278
|
+
const mergedSchema = { ...options.schema ?? {}, ...fragment };
|
|
279
|
+
return createVard({
|
|
280
|
+
...options,
|
|
281
|
+
schema: mergedSchema,
|
|
282
|
+
store
|
|
283
|
+
});
|
|
284
|
+
},
|
|
186
285
|
getDefinitions() {
|
|
187
286
|
return [...registry];
|
|
188
287
|
},
|
|
@@ -194,8 +293,56 @@ function labelFromKey(key) {
|
|
|
194
293
|
const lastSegment = key.split(".").pop() ?? key;
|
|
195
294
|
return lastSegment.replace(/([A-Z])/g, " $1").replace(/^./, (c) => c.toUpperCase()).trim();
|
|
196
295
|
}
|
|
296
|
+
|
|
297
|
+
// src/schema.ts
|
|
298
|
+
var v = {
|
|
299
|
+
string: (defaultValue, opts = {}) => ({
|
|
300
|
+
type: "string",
|
|
301
|
+
default: defaultValue,
|
|
302
|
+
...opts
|
|
303
|
+
}),
|
|
304
|
+
richtext: (defaultValue, opts = {}) => ({
|
|
305
|
+
type: "richtext",
|
|
306
|
+
default: defaultValue,
|
|
307
|
+
...opts
|
|
308
|
+
}),
|
|
309
|
+
color: (defaultValue, opts = {}) => ({
|
|
310
|
+
type: "color",
|
|
311
|
+
default: defaultValue,
|
|
312
|
+
...opts
|
|
313
|
+
}),
|
|
314
|
+
image: (defaultValue, opts = {}) => ({
|
|
315
|
+
type: "image",
|
|
316
|
+
default: defaultValue,
|
|
317
|
+
...opts
|
|
318
|
+
}),
|
|
319
|
+
boolean: (defaultValue, opts = {}) => ({
|
|
320
|
+
type: "boolean",
|
|
321
|
+
default: defaultValue,
|
|
322
|
+
...opts
|
|
323
|
+
}),
|
|
324
|
+
collection: (schema) => ({
|
|
325
|
+
type: "collection",
|
|
326
|
+
schema
|
|
327
|
+
}),
|
|
328
|
+
/**
|
|
329
|
+
* Creates a reusable schema fragment that can be merged into a Vard client
|
|
330
|
+
* via `vard.extend(fragment)`. Co-locate this with your page/component.
|
|
331
|
+
*
|
|
332
|
+
* @example
|
|
333
|
+
* // app/therapists/schema.ts
|
|
334
|
+
* export const therapistSchema = v.schema({
|
|
335
|
+
* therapists: v.collection({ name: v.string(), photo: v.image() }),
|
|
336
|
+
* });
|
|
337
|
+
*
|
|
338
|
+
* // app/therapists/page.tsx
|
|
339
|
+
* const { therapists } = await vard.extend(therapistSchema).get();
|
|
340
|
+
*/
|
|
341
|
+
schema: (schema) => schema
|
|
342
|
+
};
|
|
197
343
|
export {
|
|
198
344
|
createVard,
|
|
199
|
-
createVardFetchStore
|
|
345
|
+
createVardFetchStore,
|
|
346
|
+
v
|
|
200
347
|
};
|
|
201
348
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/fetch-store.ts","../src/client.ts"],"sourcesContent":["import type { VardStore } from \"./types\";\n\nexport interface VardFetchStoreOptions {\n /**\n * Base URL of the Vard API. Defaults to https://api.vard.app\n */\n apiBase?: string;\n\n /**\n * Workspace ID (Legacy). Defaults to process.env.VARD_WORKSPACE_ID.\n */\n workspaceId?: string;\n\n /**\n * API Key for authentication. Defaults to process.env.VARD_API_KEY.\n */\n apiKey?: string;\n\n /**\n * Custom fetch options (headers, etc.)\n */\n fetchOptions?: RequestInit;\n}\n\n/**\n * Creates a universal VardStore that fetches variable values from the Vard API.\n * Works in any environment with a global `fetch` (Browsers, Node 18+, Bun, Deno).\n */\nexport function createVardFetchStore(\n options: VardFetchStoreOptions = {}\n): VardStore & { prefetch(): Promise<void> } {\n const {\n apiBase = \"https://api.vard.app\",\n workspaceId = options.workspaceId ?? process.env.VARD_WORKSPACE_ID,\n apiKey = options.apiKey ?? process.env.VARD_API_KEY,\n fetchOptions = {},\n } = options;\n\n let resolvedValues: Map<string, unknown> | null = null;\n let fetchPromise: Promise<Map<string, unknown>> | null = null;\n\n async function fetchValues(): Promise<Map<string, unknown>> {\n const isDevelopment = process.env.NODE_ENV === \"development\";\n\n if (!apiKey && !workspaceId) {\n if (!isDevelopment) {\n console.error(\n \"\\x1b[31m[vard] Missing configuration! VARD_API_KEY is not set.\\x1b[0m\\n\" +\n \"Please set this environment variable in your production environment.\"\n );\n } else {\n console.warn(\n \"[vard] No API Key found. Running in local fallback mode (using default values).\"\n );\n }\n return new Map();\n }\n\n const url = apiKey\n ? `${apiBase}/api/content/variables`\n : `${apiBase}/v1/workspaces/${workspaceId}/variables`;\n\n try {\n const res = await fetch(url, {\n ...fetchOptions,\n headers: {\n ...fetchOptions.headers,\n ...(apiKey ? { \"X-Vard-API-Key\": apiKey } : {}),\n },\n });\n\n if (!res.ok) {\n console.warn(`[vard] Failed to fetch variables: ${res.status}`);\n return new Map();\n }\n\n const data = (await res.json()) as { key: string; value: unknown }[];\n return new Map(data.map((v) => [v.key, v.value]));\n } catch (err) {\n console.warn(\"[vard] Error fetching variable values:\", err);\n return new Map();\n }\n }\n\n return {\n get(key: string): unknown {\n return resolvedValues?.get(key);\n },\n\n async prefetch(): Promise<void> {\n if (resolvedValues) return;\n if (!fetchPromise) {\n fetchPromise = fetchValues();\n }\n resolvedValues = await fetchPromise;\n },\n };\n}\n","import type {\n VardClient,\n VardOptions,\n VardStore,\n VardVariableDefinition,\n VardVariableOptions,\n VardListItemSchema,\n InferListItem,\n VardRole,\n} from \"./types\";\n\n// ─────────────────────────────────────────────\n// No-op store (used in local dev when no workspaceId is set)\n// ─────────────────────────────────────────────\n\nlet hasLoggedNoop = false;\nconst noopStore: VardStore = {\n get: () => {\n if (!hasLoggedNoop && process.env.NODE_ENV !== \"test\") {\n console.warn(\n \"[vard] Using default values for all variables because no Store was provided to createVard().\"\n );\n hasLoggedNoop = true;\n }\n return undefined;\n },\n};\n\n// ─────────────────────────────────────────────\n// createVard — the main SDK factory\n// ─────────────────────────────────────────────\n\nimport { createVardFetchStore } from \"./fetch-store\";\n\n/**\n * Creates a Vard client instance. Call this once at the top of your site\n * (e.g. in `lib/vard.ts`) and export the result.\n *\n * @example\n * // lib/vard.ts\n * import { createVard } from \"@vard/sdk\"\n * export const vard = createVard({ apiKey: \"...\" })\n *\n * // app/page.tsx\n * import { vard } from \"@/lib/vard\"\n * const title = vard.string(\"hero.title\", \"Hello, world\")\n */\nexport function createVard(options: VardOptions = {}): VardClient {\n const store: VardStore =\n options.store ??\n (options.apiKey || options.workspaceId ? createVardFetchStore(options) : noopStore);\n\n // Registry of all declared variables — used by CLI + build pipeline\n const registry: VardVariableDefinition[] = [];\n\n function register<T>(def: VardVariableDefinition<T>): T {\n // Avoid double-registering the same key (e.g. in hot-reload scenarios)\n if (!registry.find((d) => d.key === def.key)) {\n registry.push(def as VardVariableDefinition);\n }\n\n // Resolve value: stored client value takes precedence over the default\n const stored = store.get(def.key);\n if (stored !== undefined && stored !== null) {\n return stored as T;\n }\n\n return def.defaultValue;\n }\n\n const client: VardClient = {\n string(key, fallback, opts: VardVariableOptions = {}) {\n return register<string>({\n key,\n label: opts.label ?? labelFromKey(key),\n description: opts.description,\n type: \"string\",\n defaultValue: fallback,\n editableBy: opts.editableBy ?? \"member\",\n group: opts.group,\n });\n },\n\n richtext(key, fallback, opts: VardVariableOptions = {}) {\n return register<string>({\n key,\n label: opts.label ?? labelFromKey(key),\n description: opts.description,\n type: \"richtext\",\n defaultValue: fallback,\n editableBy: opts.editableBy ?? \"member\",\n group: opts.group,\n });\n },\n\n color(key, fallback, opts: VardVariableOptions = {}) {\n return register<string>({\n key,\n label: opts.label ?? labelFromKey(key),\n description: opts.description,\n type: \"color\",\n defaultValue: fallback,\n editableBy: opts.editableBy ?? \"member\",\n group: opts.group,\n });\n },\n\n image(key, fallback, opts: VardVariableOptions = {}) {\n return register<string>({\n key,\n label: opts.label ?? labelFromKey(key),\n description: opts.description,\n type: \"image\",\n defaultValue: fallback,\n editableBy: opts.editableBy ?? \"member\",\n group: opts.group,\n });\n },\n\n boolean(key, fallback, opts: VardVariableOptions = {}) {\n return register<boolean>({\n key,\n label: opts.label ?? labelFromKey(key),\n description: opts.description,\n type: \"boolean\",\n defaultValue: fallback,\n editableBy: (opts.editableBy as VardRole) ?? \"member\",\n group: opts.group,\n });\n },\n\n list<S extends VardListItemSchema>(\n key: string,\n schema: S,\n fallback: InferListItem<S>[],\n opts: VardVariableOptions = {}\n ): InferListItem<S>[] {\n return register<InferListItem<S>[]>({\n key,\n label: opts.label ?? labelFromKey(key),\n description: opts.description,\n type: \"list\",\n defaultValue: fallback,\n editableBy: (opts.editableBy as VardRole) ?? \"member\",\n listItemSchema: schema,\n group: opts.group,\n });\n },\n\n collection<S extends VardListItemSchema>(\n key: string,\n schema: S,\n fallback: InferListItem<S>[],\n opts: Omit<VardVariableOptions, \"type\"> = {}\n ): InferListItem<S>[] {\n return register<InferListItem<S>[]>({\n key,\n label: opts.label ?? labelFromKey(key),\n description: opts.description,\n type: \"list\",\n defaultValue: fallback,\n editableBy: (opts.editableBy as VardRole) ?? \"member\",\n listItemSchema: schema,\n group: opts.group,\n isCollection: true,\n });\n },\n\n global: {\n string(key, fallback, opts = {}) {\n return client.string(key, fallback, { ...opts, group: \"Global\" } as VardVariableOptions);\n },\n richtext(key, fallback, opts = {}) {\n return client.richtext(key, fallback, { ...opts, group: \"Global\" } as VardVariableOptions);\n },\n color(key, fallback, opts = {}) {\n return client.color(key, fallback, { ...opts, group: \"Global\" } as VardVariableOptions);\n },\n image(key, fallback, opts = {}) {\n return client.image(key, fallback, { ...opts, group: \"Global\" } as VardVariableOptions);\n },\n boolean(key, fallback, opts = {}) {\n return client.boolean(key, fallback, { ...opts, group: \"Global\" } as Omit<\n VardVariableOptions,\n \"type\"\n >);\n },\n list(key, schema, fallback, opts = {}) {\n return client.list(key, schema, fallback, { ...opts, group: \"Global\" } as Omit<\n VardVariableOptions,\n \"type\"\n >);\n },\n },\n\n getDefinitions() {\n return [...registry];\n },\n store,\n };\n\n return client;\n}\n\n// ─────────────────────────────────────────────\n// Helpers\n// ─────────────────────────────────────────────\n\n/**\n * Converts a dot-notation key to a human-readable label.\n * e.g. \"hero.primaryTitle\" → \"Hero Primary Title\"\n */\nfunction labelFromKey(key: string): string {\n const lastSegment = key.split(\".\").pop() ?? key;\n // Split on camelCase boundaries and capitalise\n return lastSegment\n .replace(/([A-Z])/g, \" $1\")\n .replace(/^./, (c) => c.toUpperCase())\n .trim();\n}\n"],"mappings":";AA4BO,SAAS,qBACd,UAAiC,CAAC,GACS;AAC3C,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,cAAc,QAAQ,eAAe,QAAQ,IAAI;AAAA,IACjD,SAAS,QAAQ,UAAU,QAAQ,IAAI;AAAA,IACvC,eAAe,CAAC;AAAA,EAClB,IAAI;AAEJ,MAAI,iBAA8C;AAClD,MAAI,eAAqD;AAEzD,iBAAe,cAA6C;AAC1D,UAAM,gBAAgB,QAAQ,IAAI,aAAa;AAE/C,QAAI,CAAC,UAAU,CAAC,aAAa;AAC3B,UAAI,CAAC,eAAe;AAClB,gBAAQ;AAAA,UACN;AAAA,QAEF;AAAA,MACF,OAAO;AACL,gBAAQ;AAAA,UACN;AAAA,QACF;AAAA,MACF;AACA,aAAO,oBAAI,IAAI;AAAA,IACjB;AAEA,UAAM,MAAM,SACR,GAAG,OAAO,2BACV,GAAG,OAAO,kBAAkB,WAAW;AAE3C,QAAI;AACF,YAAM,MAAM,MAAM,MAAM,KAAK;AAAA,QAC3B,GAAG;AAAA,QACH,SAAS;AAAA,UACP,GAAG,aAAa;AAAA,UAChB,GAAI,SAAS,EAAE,kBAAkB,OAAO,IAAI,CAAC;AAAA,QAC/C;AAAA,MACF,CAAC;AAED,UAAI,CAAC,IAAI,IAAI;AACX,gBAAQ,KAAK,qCAAqC,IAAI,MAAM,EAAE;AAC9D,eAAO,oBAAI,IAAI;AAAA,MACjB;AAEA,YAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,aAAO,IAAI,IAAI,KAAK,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAAA,IAClD,SAAS,KAAK;AACZ,cAAQ,KAAK,0CAA0C,GAAG;AAC1D,aAAO,oBAAI,IAAI;AAAA,IACjB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,IAAI,KAAsB;AACxB,aAAO,gBAAgB,IAAI,GAAG;AAAA,IAChC;AAAA,IAEA,MAAM,WAA0B;AAC9B,UAAI,eAAgB;AACpB,UAAI,CAAC,cAAc;AACjB,uBAAe,YAAY;AAAA,MAC7B;AACA,uBAAiB,MAAM;AAAA,IACzB;AAAA,EACF;AACF;;;AClFA,IAAI,gBAAgB;AACpB,IAAM,YAAuB;AAAA,EAC3B,KAAK,MAAM;AACT,QAAI,CAAC,iBAAiB,QAAQ,IAAI,aAAa,QAAQ;AACrD,cAAQ;AAAA,QACN;AAAA,MACF;AACA,sBAAgB;AAAA,IAClB;AACA,WAAO;AAAA,EACT;AACF;AAqBO,SAAS,WAAW,UAAuB,CAAC,GAAe;AAChE,QAAM,QACJ,QAAQ,UACP,QAAQ,UAAU,QAAQ,cAAc,qBAAqB,OAAO,IAAI;AAG3E,QAAM,WAAqC,CAAC;AAE5C,WAAS,SAAY,KAAmC;AAEtD,QAAI,CAAC,SAAS,KAAK,CAAC,MAAM,EAAE,QAAQ,IAAI,GAAG,GAAG;AAC5C,eAAS,KAAK,GAA6B;AAAA,IAC7C;AAGA,UAAM,SAAS,MAAM,IAAI,IAAI,GAAG;AAChC,QAAI,WAAW,UAAa,WAAW,MAAM;AAC3C,aAAO;AAAA,IACT;AAEA,WAAO,IAAI;AAAA,EACb;AAEA,QAAM,SAAqB;AAAA,IACzB,OAAO,KAAK,UAAU,OAA4B,CAAC,GAAG;AACpD,aAAO,SAAiB;AAAA,QACtB;AAAA,QACA,OAAO,KAAK,SAAS,aAAa,GAAG;AAAA,QACrC,aAAa,KAAK;AAAA,QAClB,MAAM;AAAA,QACN,cAAc;AAAA,QACd,YAAY,KAAK,cAAc;AAAA,QAC/B,OAAO,KAAK;AAAA,MACd,CAAC;AAAA,IACH;AAAA,IAEA,SAAS,KAAK,UAAU,OAA4B,CAAC,GAAG;AACtD,aAAO,SAAiB;AAAA,QACtB;AAAA,QACA,OAAO,KAAK,SAAS,aAAa,GAAG;AAAA,QACrC,aAAa,KAAK;AAAA,QAClB,MAAM;AAAA,QACN,cAAc;AAAA,QACd,YAAY,KAAK,cAAc;AAAA,QAC/B,OAAO,KAAK;AAAA,MACd,CAAC;AAAA,IACH;AAAA,IAEA,MAAM,KAAK,UAAU,OAA4B,CAAC,GAAG;AACnD,aAAO,SAAiB;AAAA,QACtB;AAAA,QACA,OAAO,KAAK,SAAS,aAAa,GAAG;AAAA,QACrC,aAAa,KAAK;AAAA,QAClB,MAAM;AAAA,QACN,cAAc;AAAA,QACd,YAAY,KAAK,cAAc;AAAA,QAC/B,OAAO,KAAK;AAAA,MACd,CAAC;AAAA,IACH;AAAA,IAEA,MAAM,KAAK,UAAU,OAA4B,CAAC,GAAG;AACnD,aAAO,SAAiB;AAAA,QACtB;AAAA,QACA,OAAO,KAAK,SAAS,aAAa,GAAG;AAAA,QACrC,aAAa,KAAK;AAAA,QAClB,MAAM;AAAA,QACN,cAAc;AAAA,QACd,YAAY,KAAK,cAAc;AAAA,QAC/B,OAAO,KAAK;AAAA,MACd,CAAC;AAAA,IACH;AAAA,IAEA,QAAQ,KAAK,UAAU,OAA4B,CAAC,GAAG;AACrD,aAAO,SAAkB;AAAA,QACvB;AAAA,QACA,OAAO,KAAK,SAAS,aAAa,GAAG;AAAA,QACrC,aAAa,KAAK;AAAA,QAClB,MAAM;AAAA,QACN,cAAc;AAAA,QACd,YAAa,KAAK,cAA2B;AAAA,QAC7C,OAAO,KAAK;AAAA,MACd,CAAC;AAAA,IACH;AAAA,IAEA,KACE,KACA,QACA,UACA,OAA4B,CAAC,GACT;AACpB,aAAO,SAA6B;AAAA,QAClC;AAAA,QACA,OAAO,KAAK,SAAS,aAAa,GAAG;AAAA,QACrC,aAAa,KAAK;AAAA,QAClB,MAAM;AAAA,QACN,cAAc;AAAA,QACd,YAAa,KAAK,cAA2B;AAAA,QAC7C,gBAAgB;AAAA,QAChB,OAAO,KAAK;AAAA,MACd,CAAC;AAAA,IACH;AAAA,IAEA,WACE,KACA,QACA,UACA,OAA0C,CAAC,GACvB;AACpB,aAAO,SAA6B;AAAA,QAClC;AAAA,QACA,OAAO,KAAK,SAAS,aAAa,GAAG;AAAA,QACrC,aAAa,KAAK;AAAA,QAClB,MAAM;AAAA,QACN,cAAc;AAAA,QACd,YAAa,KAAK,cAA2B;AAAA,QAC7C,gBAAgB;AAAA,QAChB,OAAO,KAAK;AAAA,QACZ,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AAAA,IAEA,QAAQ;AAAA,MACN,OAAO,KAAK,UAAU,OAAO,CAAC,GAAG;AAC/B,eAAO,OAAO,OAAO,KAAK,UAAU,EAAE,GAAG,MAAM,OAAO,SAAS,CAAwB;AAAA,MACzF;AAAA,MACA,SAAS,KAAK,UAAU,OAAO,CAAC,GAAG;AACjC,eAAO,OAAO,SAAS,KAAK,UAAU,EAAE,GAAG,MAAM,OAAO,SAAS,CAAwB;AAAA,MAC3F;AAAA,MACA,MAAM,KAAK,UAAU,OAAO,CAAC,GAAG;AAC9B,eAAO,OAAO,MAAM,KAAK,UAAU,EAAE,GAAG,MAAM,OAAO,SAAS,CAAwB;AAAA,MACxF;AAAA,MACA,MAAM,KAAK,UAAU,OAAO,CAAC,GAAG;AAC9B,eAAO,OAAO,MAAM,KAAK,UAAU,EAAE,GAAG,MAAM,OAAO,SAAS,CAAwB;AAAA,MACxF;AAAA,MACA,QAAQ,KAAK,UAAU,OAAO,CAAC,GAAG;AAChC,eAAO,OAAO,QAAQ,KAAK,UAAU,EAAE,GAAG,MAAM,OAAO,SAAS,CAG/D;AAAA,MACH;AAAA,MACA,KAAK,KAAK,QAAQ,UAAU,OAAO,CAAC,GAAG;AACrC,eAAO,OAAO,KAAK,KAAK,QAAQ,UAAU,EAAE,GAAG,MAAM,OAAO,SAAS,CAGpE;AAAA,MACH;AAAA,IACF;AAAA,IAEA,iBAAiB;AACf,aAAO,CAAC,GAAG,QAAQ;AAAA,IACrB;AAAA,IACA;AAAA,EACF;AAEA,SAAO;AACT;AAUA,SAAS,aAAa,KAAqB;AACzC,QAAM,cAAc,IAAI,MAAM,GAAG,EAAE,IAAI,KAAK;AAE5C,SAAO,YACJ,QAAQ,YAAY,KAAK,EACzB,QAAQ,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,EACpC,KAAK;AACV;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/fetch-store.ts","../src/client.ts","../src/schema.ts"],"sourcesContent":["import type { VardStore } from \"./types\";\n\nexport interface VardFetchStoreOptions {\n /**\n * Base URL of the Vard API. Defaults to https://api.vard.app\n */\n apiBase?: string;\n\n /**\n * API Key for authentication. Defaults to process.env.VARD_API_KEY.\n */\n apiKey?: string;\n\n /**\n * Custom fetch options (headers, etc.)\n */\n fetchOptions?: RequestInit;\n}\n\n/**\n * Creates a universal VardStore that fetches variable values from the Vard API.\n * Works in any environment with a global `fetch` (Browsers, Node 18+, Bun, Deno).\n */\nexport function createVardFetchStore(\n options: VardFetchStoreOptions = {}\n): VardStore & { prefetch(): Promise<void> } {\n const {\n apiBase = options.apiBase ??\n process.env.VARD_API_BASE ??\n process.env.NEXT_PUBLIC_VARD_API_BASE ??\n \"https://dash.vard.app\",\n apiKey = options.apiKey ?? process.env.VARD_API_KEY,\n fetchOptions = {},\n } = options;\n\n let resolvedValues: Map<string, unknown> | null = null;\n let structuredContent: any = null;\n let fetchPromise: Promise<{ variables: Map<string, unknown>; structured: any }> | null = null;\n\n async function fetchValues(): Promise<{ variables: Map<string, unknown>; structured: any }> {\n const isDevelopment = process.env.NODE_ENV === \"development\";\n\n if (!apiKey) {\n if (!isDevelopment) {\n console.error(\n \"\\x1b[31m[vard] Missing configuration! VARD_API_KEY is not set.\\x1b[0m\\n\" +\n \"Please set this environment variable in your production environment.\"\n );\n } else {\n console.warn(\n \"[vard] No API Key found. Running in local fallback mode (using default values).\"\n );\n }\n return { variables: new Map(), structured: {} };\n }\n\n const url = `${apiBase}/api/content/variables?structured=true`;\n\n try {\n const res = await fetch(url, {\n ...fetchOptions,\n headers: {\n ...fetchOptions.headers,\n \"X-Vard-API-Key\": apiKey,\n },\n });\n\n if (!res.ok) {\n console.warn(`[vard] Failed to fetch variables: ${res.status}`);\n return { variables: new Map(), structured: {} };\n }\n\n const data = (await res.json()) as any;\n\n // Handle both legacy (array) and new (object with structured) responses\n if (Array.isArray(data)) {\n return {\n variables: new Map(data.map((v: any) => [v.key, v.value])),\n structured: {},\n };\n }\n\n return {\n variables: new Map(data.variables.map((v: any) => [v.key, v.value])),\n structured: data.structured || {},\n };\n } catch (err) {\n return { variables: new Map(), structured: {} };\n }\n }\n\n return {\n get(key: string): unknown {\n return resolvedValues?.get(key);\n },\n\n getStructured(): any {\n return structuredContent;\n },\n\n async prefetch(): Promise<void> {\n if (resolvedValues) return;\n if (!fetchPromise) {\n fetchPromise = fetchValues();\n }\n const result = await fetchPromise;\n resolvedValues = result.variables;\n structuredContent = result.structured;\n },\n };\n}\n","import {\n VardClient,\n VardOptions,\n VardStore,\n VardVariableDefinition,\n VardVariableOptions,\n VardListItemSchema,\n InferListItem,\n VardRole,\n VardVariableType,\n} from \"./types\";\nimport {\n VardSchema,\n InferSchema,\n VardField,\n VardCollection,\n VardSchemaFragment,\n MergeSchema,\n} from \"./schema\";\nimport { createVardFetchStore } from \"./fetch-store\";\n\n// ─────────────────────────────────────────────\n// No-op store (used in local dev when no apiKey is set)\n// ─────────────────────────────────────────────\n\nlet hasLoggedNoop = false;\nconst noopStore: VardStore = {\n get: () => {\n if (!hasLoggedNoop && process.env.NODE_ENV !== \"test\") {\n console.warn(\n \"[vard] Using default values for all variables because no Store was provided to createVard().\"\n );\n hasLoggedNoop = true;\n }\n return undefined;\n },\n};\n\n// ─────────────────────────────────────────────\n// createVard — the main SDK factory\n// ─────────────────────────────────────────────\n\n/**\n * Creates a Vard client instance. Call this once at the top of your site\n * (e.g. in `lib/vard.ts`) and export the result.\n */\nexport function createVard<S extends VardSchema = any>(\n options: VardOptions<S> = {}\n): VardClient<S> {\n const store: VardStore =\n options.store ?? (options.apiKey ? createVardFetchStore(options) : noopStore);\n\n // Registry of all declared variables — used by CLI + build pipeline\n const registry: VardVariableDefinition[] = [];\n\n function register<T>(def: VardVariableDefinition<T>): T {\n if (!registry.find((d) => d.key === def.key)) {\n registry.push(def as VardVariableDefinition);\n }\n\n const stored = store.get(def.key);\n if (stored !== undefined && stored !== null) {\n return stored as T;\n }\n\n return def.defaultValue;\n }\n\n // ─────────────────────────────────────────────\n // Schema Traversal\n // ─────────────────────────────────────────────\n\n function flattenSchema(schema: VardSchema, prefix = \"\"): any {\n const result: any = {};\n\n for (const [key, value] of Object.entries(schema)) {\n const fullKey = prefix ? `${prefix}.${key}` : key;\n\n if (typeof value === \"object\" && value !== null && \"type\" in value) {\n // It's a field or collection\n const field = value as VardField | VardCollection;\n\n if (field.type === \"collection\") {\n // Flatten collection schema but keep it as a 'list' type for the registry\n const collection = field as VardCollection;\n const listItemSchema: Record<string, string> = {};\n for (const [fKey, fVal] of Object.entries(collection.schema)) {\n listItemSchema[fKey] = (fVal as VardField).type;\n }\n\n register({\n key: fullKey,\n label: labelFromKey(key),\n type: \"list\",\n defaultValue: [],\n editableBy: \"member\",\n listItemSchema: listItemSchema as VardListItemSchema,\n isCollection: true,\n });\n\n // In the returned object, this remains a placeholder or is proxied to the store\n Object.defineProperty(result, key, {\n get: () => store.get(fullKey) ?? [],\n enumerable: true,\n });\n } else {\n // It's a plain field\n const vardField = field as VardField;\n register({\n key: fullKey,\n label: vardField.label ?? labelFromKey(key),\n description: vardField.description,\n type: vardField.type,\n defaultValue: vardField.default,\n editableBy: vardField.editableBy ?? \"member\",\n group: vardField.group,\n });\n\n Object.defineProperty(result, key, {\n get: () => store.get(fullKey) ?? vardField.default,\n enumerable: true,\n });\n }\n } else if (typeof value === \"object\" && value !== null) {\n // It's a nested object\n result[key] = flattenSchema(value as VardSchema, fullKey);\n }\n }\n\n return result;\n }\n\n // Auto-sync schema in development\n if (options.schema && process.env.NODE_ENV === \"development\" && options.apiKey) {\n flattenSchema(options.schema);\n const definitions = [...registry];\n const apiBase =\n process.env.VARD_API_BASE ?? process.env.NEXT_PUBLIC_VARD_API_BASE ?? \"https://dash.vard.app\";\n\n fetch(`${apiBase}/api/content/variables/sync`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-Vard-API-Key\": options.apiKey,\n },\n body: JSON.stringify({\n definitions,\n schema: options.schema,\n }),\n }).catch((err) => console.warn(\"[vard] Auto-sync failed:\", err));\n }\n\n const client: VardClient<S> = {\n define<NS extends VardSchema>(schema: NS): InferSchema<NS> {\n return flattenSchema(schema) as InferSchema<NS>;\n },\n\n async get(): Promise<InferSchema<S>> {\n if (store.prefetch) {\n await store.prefetch();\n }\n if (store.getStructured) {\n const structured = store.getStructured();\n if (structured && Object.keys(structured).length > 0) {\n return structured as InferSchema<S>;\n }\n }\n return flattenSchema(options.schema ?? {}) as InferSchema<S>;\n },\n\n string(key, fallback, opts: VardVariableOptions = {}) {\n return register<string>({\n key,\n label: opts.label ?? labelFromKey(key),\n description: opts.description,\n type: \"string\",\n defaultValue: fallback,\n editableBy: opts.editableBy ?? \"member\",\n group: opts.group,\n });\n },\n\n richtext(key, fallback, opts: VardVariableOptions = {}) {\n return register<string>({\n key,\n label: opts.label ?? labelFromKey(key),\n description: opts.description,\n type: \"richtext\",\n defaultValue: fallback,\n editableBy: opts.editableBy ?? \"member\",\n group: opts.group,\n });\n },\n\n color(key, fallback, opts: VardVariableOptions = {}) {\n return register<string>({\n key,\n label: opts.label ?? labelFromKey(key),\n description: opts.description,\n type: \"color\",\n defaultValue: fallback,\n editableBy: opts.editableBy ?? \"member\",\n group: opts.group,\n });\n },\n\n image(key, fallback, opts: VardVariableOptions = {}) {\n return register<string>({\n key,\n label: opts.label ?? labelFromKey(key),\n description: opts.description,\n type: \"image\",\n defaultValue: fallback,\n editableBy: opts.editableBy ?? \"member\",\n group: opts.group,\n });\n },\n\n boolean(key, fallback, opts: VardVariableOptions = {}) {\n return register<boolean>({\n key,\n label: opts.label ?? labelFromKey(key),\n description: opts.description,\n type: \"boolean\",\n defaultValue: fallback,\n editableBy: (opts.editableBy as VardRole) ?? \"member\",\n group: opts.group,\n });\n },\n\n list<LS extends VardListItemSchema>(\n key: string,\n schema: LS,\n fallback: InferListItem<LS>[],\n opts: VardVariableOptions = {}\n ): InferListItem<LS>[] {\n return register<InferListItem<LS>[]>({\n key,\n label: opts.label ?? labelFromKey(key),\n description: opts.description,\n type: \"list\",\n defaultValue: fallback,\n editableBy: (opts.editableBy as VardRole) ?? \"member\",\n listItemSchema: schema,\n group: opts.group,\n });\n },\n\n collection<LS extends VardListItemSchema>(\n key: string,\n schema: LS,\n fallback: InferListItem<LS>[],\n opts: Omit<VardVariableOptions, \"type\"> = {}\n ): InferListItem<LS>[] {\n return register<InferListItem<LS>[]>({\n key,\n label: opts.label ?? labelFromKey(key),\n description: opts.description,\n type: \"list\",\n defaultValue: fallback,\n editableBy: (opts.editableBy as VardRole) ?? \"member\",\n listItemSchema: schema,\n group: opts.group,\n isCollection: true,\n });\n },\n\n global: {\n string(key, fallback, opts = {}) {\n return client.string(key, fallback, { ...opts, group: \"Global\" } as VardVariableOptions);\n },\n richtext(key, fallback, opts = {}) {\n return client.richtext(key, fallback, { ...opts, group: \"Global\" } as VardVariableOptions);\n },\n color(key, fallback, opts = {}) {\n return client.color(key, fallback, { ...opts, group: \"Global\" } as VardVariableOptions);\n },\n image(key, fallback, opts = {}) {\n return client.image(key, fallback, { ...opts, group: \"Global\" } as VardVariableOptions);\n },\n boolean(key, fallback, opts = {}) {\n return client.boolean(key, fallback, { ...opts, group: \"Global\" } as Omit<\n VardVariableOptions,\n \"type\"\n >);\n },\n list(key, schema, fallback, opts = {}) {\n return client.list(key, schema, fallback, { ...opts, group: \"Global\" } as Omit<\n VardVariableOptions,\n \"type\"\n >);\n },\n },\n\n extend<E extends VardSchema>(fragment: VardSchemaFragment<E>): VardClient<MergeSchema<S, E>> {\n // Merge the base schema with the fragment — the fragment keys win on collision\n const mergedSchema = { ...(options.schema ?? {}), ...fragment } as unknown as MergeSchema<\n S,\n E\n >;\n // Return a new client with the merged schema, sharing the same store & registry.\n // We pass the in-memory store directly so there is no second fetch.\n return createVard<MergeSchema<S, E>>({\n ...options,\n schema: mergedSchema,\n store,\n });\n },\n\n getDefinitions() {\n return [...registry];\n },\n store,\n };\n\n return client;\n}\n\n// ─────────────────────────────────────────────\n// Helpers\n// ─────────────────────────────────────────────\n\nfunction labelFromKey(key: string): string {\n const lastSegment = key.split(\".\").pop() ?? key;\n return lastSegment\n .replace(/([A-Z])/g, \" $1\")\n .replace(/^./, (c) => c.toUpperCase())\n .trim();\n}\n","import { VardVariableType, VardRole } from \"./types\";\n\nexport interface VardFieldOptions<T = any> {\n label?: string;\n description?: string;\n editableBy?: VardRole;\n group?: string;\n default?: T;\n}\n\nexport interface VardField<T = any> extends VardFieldOptions<T> {\n type: VardVariableType;\n}\n\nexport interface VardCollection<S extends Record<string, VardField | any> = any> {\n type: \"collection\";\n schema: S;\n}\n\nexport type VardSchemaValue = VardField | VardCollection | { [key: string]: VardSchemaValue };\n\nexport type VardSchema = Record<string, VardSchemaValue>;\n\n/**\n * A branded schema fragment created with `v.schema()`. Use with `vard.extend()`\n * to compose schemas defined across multiple files.\n */\nexport type VardSchemaFragment<S extends VardSchema> = S & {\n readonly __fragment: true;\n};\n\n/**\n * Merges two VardSchema types, with B's keys overriding A on collision.\n */\nexport type MergeSchema<A extends VardSchema, B extends VardSchema> = Omit<A, keyof B> & B;\n\n// ─────────────────────────────────────────────\n// The `v` helper object for schema definition\n// ─────────────────────────────────────────────\n\nexport const v = {\n string: (\n defaultValue?: string,\n opts: Omit<VardFieldOptions<string>, \"default\"> = {}\n ): VardField<string> => ({\n type: \"string\",\n default: defaultValue,\n ...opts,\n }),\n\n richtext: (\n defaultValue?: string,\n opts: Omit<VardFieldOptions<string>, \"default\"> = {}\n ): VardField<string> => ({\n type: \"richtext\",\n default: defaultValue,\n ...opts,\n }),\n\n color: (\n defaultValue?: string,\n opts: Omit<VardFieldOptions<string>, \"default\"> = {}\n ): VardField<string> => ({\n type: \"color\",\n default: defaultValue,\n ...opts,\n }),\n\n image: (\n defaultValue?: string,\n opts: Omit<VardFieldOptions<string>, \"default\"> = {}\n ): VardField<string> => ({\n type: \"image\",\n default: defaultValue,\n ...opts,\n }),\n\n boolean: (\n defaultValue?: boolean,\n opts: Omit<VardFieldOptions<boolean>, \"default\"> = {}\n ): VardField<boolean> => ({\n type: \"boolean\",\n default: defaultValue,\n ...opts,\n }),\n\n collection: <S extends Record<string, VardField | any>>(schema: S): VardCollection<S> => ({\n type: \"collection\",\n schema,\n }),\n\n /**\n * Creates a reusable schema fragment that can be merged into a Vard client\n * via `vard.extend(fragment)`. Co-locate this with your page/component.\n *\n * @example\n * // app/therapists/schema.ts\n * export const therapistSchema = v.schema({\n * therapists: v.collection({ name: v.string(), photo: v.image() }),\n * });\n *\n * // app/therapists/page.tsx\n * const { therapists } = await vard.extend(therapistSchema).get();\n */\n schema: <S extends VardSchema>(schema: S): VardSchemaFragment<S> =>\n schema as VardSchemaFragment<S>,\n};\n\n// ─────────────────────────────────────────────\n// Type inference for schema objects\n// ─────────────────────────────────────────────\n\nexport type InferSchema<T> = {\n [K in keyof T]: T[K] extends VardField<infer U>\n ? U\n : T[K] extends VardCollection<infer S>\n ? InferSchema<S>[]\n : T[K] extends object\n ? InferSchema<T[K]>\n : never;\n};\n"],"mappings":"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","names":["v"]}
|
package/dist/next.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as VardOptions, b as VardClient, c as VardStore } from './types-Dd-I7jwP.mjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @vard/sdk — Next.js adapter
|
|
@@ -13,15 +13,9 @@ import { V as VardOptions, a as VardClient, b as VardStore } from './types-eJuYa
|
|
|
13
13
|
* import { createVard } from "@vard/sdk"
|
|
14
14
|
*
|
|
15
15
|
* export const vard = createVard({
|
|
16
|
-
*
|
|
16
|
+
* apiKey: process.env.VARD_API_KEY,
|
|
17
17
|
* store: createVardNextAdapter(),
|
|
18
18
|
* })
|
|
19
|
-
*
|
|
20
|
-
* The adapter fetches variable values from the Vard API:
|
|
21
|
-
* GET https://api.vard.app/v1/workspaces/{workspaceId}/variables
|
|
22
|
-
*
|
|
23
|
-
* In local development (no VARD_WORKSPACE_ID set) it silently falls back
|
|
24
|
-
* to default values so your site works without any Vard account.
|
|
25
19
|
*/
|
|
26
20
|
|
|
27
21
|
interface VardNextAdapterOptions {
|
|
@@ -29,10 +23,6 @@ interface VardNextAdapterOptions {
|
|
|
29
23
|
* Base URL of the Vard API. Defaults to https://api.vard.app
|
|
30
24
|
*/
|
|
31
25
|
apiBase?: string;
|
|
32
|
-
/**
|
|
33
|
-
* Workspace ID. Falls back to process.env.VARD_WORKSPACE_ID.
|
|
34
|
-
*/
|
|
35
|
-
workspaceId?: string;
|
|
36
26
|
/**
|
|
37
27
|
* API Key for authentication. Falls back to process.env.VARD_API_KEY.
|
|
38
28
|
*/
|
package/dist/next.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { a as VardOptions, b as VardClient, c as VardStore } from './types-Dd-I7jwP.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @vard/sdk — Next.js adapter
|
|
@@ -13,15 +13,9 @@ import { V as VardOptions, a as VardClient, b as VardStore } from './types-eJuYa
|
|
|
13
13
|
* import { createVard } from "@vard/sdk"
|
|
14
14
|
*
|
|
15
15
|
* export const vard = createVard({
|
|
16
|
-
*
|
|
16
|
+
* apiKey: process.env.VARD_API_KEY,
|
|
17
17
|
* store: createVardNextAdapter(),
|
|
18
18
|
* })
|
|
19
|
-
*
|
|
20
|
-
* The adapter fetches variable values from the Vard API:
|
|
21
|
-
* GET https://api.vard.app/v1/workspaces/{workspaceId}/variables
|
|
22
|
-
*
|
|
23
|
-
* In local development (no VARD_WORKSPACE_ID set) it silently falls back
|
|
24
|
-
* to default values so your site works without any Vard account.
|
|
25
19
|
*/
|
|
26
20
|
|
|
27
21
|
interface VardNextAdapterOptions {
|
|
@@ -29,10 +23,6 @@ interface VardNextAdapterOptions {
|
|
|
29
23
|
* Base URL of the Vard API. Defaults to https://api.vard.app
|
|
30
24
|
*/
|
|
31
25
|
apiBase?: string;
|
|
32
|
-
/**
|
|
33
|
-
* Workspace ID. Falls back to process.env.VARD_WORKSPACE_ID.
|
|
34
|
-
*/
|
|
35
|
-
workspaceId?: string;
|
|
36
26
|
/**
|
|
37
27
|
* API Key for authentication. Falls back to process.env.VARD_API_KEY.
|
|
38
28
|
*/
|
package/dist/next.js
CHANGED
|
@@ -29,16 +29,16 @@ module.exports = __toCommonJS(next_exports);
|
|
|
29
29
|
// src/fetch-store.ts
|
|
30
30
|
function createVardFetchStore(options = {}) {
|
|
31
31
|
const {
|
|
32
|
-
apiBase = "https://
|
|
33
|
-
workspaceId = options.workspaceId ?? process.env.VARD_WORKSPACE_ID,
|
|
32
|
+
apiBase = options.apiBase ?? process.env.VARD_API_BASE ?? process.env.NEXT_PUBLIC_VARD_API_BASE ?? "https://dash.vard.app",
|
|
34
33
|
apiKey = options.apiKey ?? process.env.VARD_API_KEY,
|
|
35
34
|
fetchOptions = {}
|
|
36
35
|
} = options;
|
|
37
36
|
let resolvedValues = null;
|
|
37
|
+
let structuredContent = null;
|
|
38
38
|
let fetchPromise = null;
|
|
39
39
|
async function fetchValues() {
|
|
40
40
|
const isDevelopment = process.env.NODE_ENV === "development";
|
|
41
|
-
if (!apiKey
|
|
41
|
+
if (!apiKey) {
|
|
42
42
|
if (!isDevelopment) {
|
|
43
43
|
console.error(
|
|
44
44
|
"\x1B[31m[vard] Missing configuration! VARD_API_KEY is not set.\x1B[0m\nPlease set this environment variable in your production environment."
|
|
@@ -48,38 +48,51 @@ function createVardFetchStore(options = {}) {
|
|
|
48
48
|
"[vard] No API Key found. Running in local fallback mode (using default values)."
|
|
49
49
|
);
|
|
50
50
|
}
|
|
51
|
-
return /* @__PURE__ */ new Map();
|
|
51
|
+
return { variables: /* @__PURE__ */ new Map(), structured: {} };
|
|
52
52
|
}
|
|
53
|
-
const url =
|
|
53
|
+
const url = `${apiBase}/api/content/variables?structured=true`;
|
|
54
54
|
try {
|
|
55
55
|
const res = await fetch(url, {
|
|
56
56
|
...fetchOptions,
|
|
57
57
|
headers: {
|
|
58
58
|
...fetchOptions.headers,
|
|
59
|
-
|
|
59
|
+
"X-Vard-API-Key": apiKey
|
|
60
60
|
}
|
|
61
61
|
});
|
|
62
62
|
if (!res.ok) {
|
|
63
63
|
console.warn(`[vard] Failed to fetch variables: ${res.status}`);
|
|
64
|
-
return /* @__PURE__ */ new Map();
|
|
64
|
+
return { variables: /* @__PURE__ */ new Map(), structured: {} };
|
|
65
65
|
}
|
|
66
66
|
const data = await res.json();
|
|
67
|
-
|
|
67
|
+
if (Array.isArray(data)) {
|
|
68
|
+
return {
|
|
69
|
+
variables: new Map(data.map((v) => [v.key, v.value])),
|
|
70
|
+
structured: {}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
variables: new Map(data.variables.map((v) => [v.key, v.value])),
|
|
75
|
+
structured: data.structured || {}
|
|
76
|
+
};
|
|
68
77
|
} catch (err) {
|
|
69
|
-
|
|
70
|
-
return /* @__PURE__ */ new Map();
|
|
78
|
+
return { variables: /* @__PURE__ */ new Map(), structured: {} };
|
|
71
79
|
}
|
|
72
80
|
}
|
|
73
81
|
return {
|
|
74
82
|
get(key) {
|
|
75
83
|
return resolvedValues?.get(key);
|
|
76
84
|
},
|
|
85
|
+
getStructured() {
|
|
86
|
+
return structuredContent;
|
|
87
|
+
},
|
|
77
88
|
async prefetch() {
|
|
78
89
|
if (resolvedValues) return;
|
|
79
90
|
if (!fetchPromise) {
|
|
80
91
|
fetchPromise = fetchValues();
|
|
81
92
|
}
|
|
82
|
-
|
|
93
|
+
const result = await fetchPromise;
|
|
94
|
+
resolvedValues = result.variables;
|
|
95
|
+
structuredContent = result.structured;
|
|
83
96
|
}
|
|
84
97
|
};
|
|
85
98
|
}
|
|
@@ -98,7 +111,7 @@ var noopStore = {
|
|
|
98
111
|
}
|
|
99
112
|
};
|
|
100
113
|
function createVard(options = {}) {
|
|
101
|
-
const store = options.store ?? (options.apiKey
|
|
114
|
+
const store = options.store ?? (options.apiKey ? createVardFetchStore(options) : noopStore);
|
|
102
115
|
const registry = [];
|
|
103
116
|
function register(def) {
|
|
104
117
|
if (!registry.find((d) => d.key === def.key)) {
|
|
@@ -110,7 +123,85 @@ function createVard(options = {}) {
|
|
|
110
123
|
}
|
|
111
124
|
return def.defaultValue;
|
|
112
125
|
}
|
|
126
|
+
function flattenSchema(schema, prefix = "") {
|
|
127
|
+
const result = {};
|
|
128
|
+
for (const [key, value] of Object.entries(schema)) {
|
|
129
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
130
|
+
if (typeof value === "object" && value !== null && "type" in value) {
|
|
131
|
+
const field = value;
|
|
132
|
+
if (field.type === "collection") {
|
|
133
|
+
const collection = field;
|
|
134
|
+
const listItemSchema = {};
|
|
135
|
+
for (const [fKey, fVal] of Object.entries(collection.schema)) {
|
|
136
|
+
listItemSchema[fKey] = fVal.type;
|
|
137
|
+
}
|
|
138
|
+
register({
|
|
139
|
+
key: fullKey,
|
|
140
|
+
label: labelFromKey(key),
|
|
141
|
+
type: "list",
|
|
142
|
+
defaultValue: [],
|
|
143
|
+
editableBy: "member",
|
|
144
|
+
listItemSchema,
|
|
145
|
+
isCollection: true
|
|
146
|
+
});
|
|
147
|
+
Object.defineProperty(result, key, {
|
|
148
|
+
get: () => store.get(fullKey) ?? [],
|
|
149
|
+
enumerable: true
|
|
150
|
+
});
|
|
151
|
+
} else {
|
|
152
|
+
const vardField = field;
|
|
153
|
+
register({
|
|
154
|
+
key: fullKey,
|
|
155
|
+
label: vardField.label ?? labelFromKey(key),
|
|
156
|
+
description: vardField.description,
|
|
157
|
+
type: vardField.type,
|
|
158
|
+
defaultValue: vardField.default,
|
|
159
|
+
editableBy: vardField.editableBy ?? "member",
|
|
160
|
+
group: vardField.group
|
|
161
|
+
});
|
|
162
|
+
Object.defineProperty(result, key, {
|
|
163
|
+
get: () => store.get(fullKey) ?? vardField.default,
|
|
164
|
+
enumerable: true
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
} else if (typeof value === "object" && value !== null) {
|
|
168
|
+
result[key] = flattenSchema(value, fullKey);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
if (options.schema && process.env.NODE_ENV === "development" && options.apiKey) {
|
|
174
|
+
flattenSchema(options.schema);
|
|
175
|
+
const definitions = [...registry];
|
|
176
|
+
const apiBase = process.env.VARD_API_BASE ?? process.env.NEXT_PUBLIC_VARD_API_BASE ?? "https://dash.vard.app";
|
|
177
|
+
fetch(`${apiBase}/api/content/variables/sync`, {
|
|
178
|
+
method: "POST",
|
|
179
|
+
headers: {
|
|
180
|
+
"Content-Type": "application/json",
|
|
181
|
+
"X-Vard-API-Key": options.apiKey
|
|
182
|
+
},
|
|
183
|
+
body: JSON.stringify({
|
|
184
|
+
definitions,
|
|
185
|
+
schema: options.schema
|
|
186
|
+
})
|
|
187
|
+
}).catch((err) => console.warn("[vard] Auto-sync failed:", err));
|
|
188
|
+
}
|
|
113
189
|
const client = {
|
|
190
|
+
define(schema) {
|
|
191
|
+
return flattenSchema(schema);
|
|
192
|
+
},
|
|
193
|
+
async get() {
|
|
194
|
+
if (store.prefetch) {
|
|
195
|
+
await store.prefetch();
|
|
196
|
+
}
|
|
197
|
+
if (store.getStructured) {
|
|
198
|
+
const structured = store.getStructured();
|
|
199
|
+
if (structured && Object.keys(structured).length > 0) {
|
|
200
|
+
return structured;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return flattenSchema(options.schema ?? {});
|
|
204
|
+
},
|
|
114
205
|
string(key, fallback, opts = {}) {
|
|
115
206
|
return register({
|
|
116
207
|
key,
|
|
@@ -211,6 +302,14 @@ function createVard(options = {}) {
|
|
|
211
302
|
return client.list(key, schema, fallback, { ...opts, group: "Global" });
|
|
212
303
|
}
|
|
213
304
|
},
|
|
305
|
+
extend(fragment) {
|
|
306
|
+
const mergedSchema = { ...options.schema ?? {}, ...fragment };
|
|
307
|
+
return createVard({
|
|
308
|
+
...options,
|
|
309
|
+
schema: mergedSchema,
|
|
310
|
+
store
|
|
311
|
+
});
|
|
312
|
+
},
|
|
214
313
|
getDefinitions() {
|
|
215
314
|
return [...registry];
|
|
216
315
|
},
|
|
@@ -225,12 +324,12 @@ function labelFromKey(key) {
|
|
|
225
324
|
|
|
226
325
|
// src/next.ts
|
|
227
326
|
function createVardNextAdapter(options = {}) {
|
|
228
|
-
const { cache = "
|
|
327
|
+
const { cache = "no-store", revalidate, ...rest } = options;
|
|
229
328
|
return createVardFetchStore({
|
|
230
329
|
...rest,
|
|
231
330
|
fetchOptions: {
|
|
232
331
|
cache,
|
|
233
|
-
...revalidate !== void 0 && cache === "force-cache" ? { next: { revalidate } } : {}
|
|
332
|
+
...revalidate !== void 0 && cache === "force-cache" ? { next: { revalidate, tags: ["variables"] } } : {}
|
|
234
333
|
}
|
|
235
334
|
});
|
|
236
335
|
}
|