@squaredr/fieldcraft-pro 1.0.0 → 1.1.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.
- package/README.md +53 -36
- package/dist/{chunk-MQGR25NG.mjs → chunk-7LQW5QYT.mjs} +1 -3
- package/dist/{chunk-DDQDYTMB.mjs → chunk-CJBC3KWB.mjs} +1 -1
- package/dist/{chunk-LOFGBNJV.mjs → chunk-RSU3X25P.mjs} +1 -1
- package/dist/chunk-VECQKSWS.mjs +582 -0
- package/dist/form-builder/index.js +324 -4
- package/dist/form-builder/index.mjs +2 -1
- package/dist/index.d.mts +52 -3
- package/dist/index.d.ts +52 -3
- package/dist/index.js +587 -30
- package/dist/index.mjs +5 -4
- package/dist/response-viewer/index.js +324 -4
- package/dist/response-viewer/index.mjs +2 -1
- package/dist/theme-editor/index.js +324 -4
- package/dist/theme-editor/index.mjs +2 -1
- package/package.json +12 -4
package/dist/index.js
CHANGED
|
@@ -1,16 +1,591 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var fieldcraftProLicense = require('@squaredr/fieldcraft-pro-license');
|
|
4
3
|
var react = require('react');
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var core = require('@dnd-kit/core');
|
|
6
6
|
var lucideReact = require('lucide-react');
|
|
7
7
|
var fieldcraftReact = require('@squaredr/fieldcraft-react');
|
|
8
8
|
var fieldcraftCore = require('@squaredr/fieldcraft-core');
|
|
9
9
|
var clsx = require('clsx');
|
|
10
10
|
var tailwindMerge = require('tailwind-merge');
|
|
11
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
12
11
|
|
|
13
|
-
//
|
|
12
|
+
// ../license/dist/index.mjs
|
|
13
|
+
var LEGACY_TIER_MAP = {
|
|
14
|
+
"01": "starter",
|
|
15
|
+
"02": "pro",
|
|
16
|
+
"03": "business",
|
|
17
|
+
"04": "enterprise"
|
|
18
|
+
};
|
|
19
|
+
var TIER_MAP_NUMERIC = {
|
|
20
|
+
1: "starter",
|
|
21
|
+
2: "pro",
|
|
22
|
+
3: "business",
|
|
23
|
+
4: "enterprise"
|
|
24
|
+
};
|
|
25
|
+
var PRO_FEATURES = [
|
|
26
|
+
"SchemaEditor",
|
|
27
|
+
"ResponseViewer",
|
|
28
|
+
"ThemeEditor",
|
|
29
|
+
"FormBuilder",
|
|
30
|
+
"ApiManager",
|
|
31
|
+
"Analytics"
|
|
32
|
+
];
|
|
33
|
+
var ALL_FEATURES = [
|
|
34
|
+
...PRO_FEATURES,
|
|
35
|
+
"Telehealth"
|
|
36
|
+
];
|
|
37
|
+
var TIER_FEATURES = {
|
|
38
|
+
starter: ["SchemaEditor", "ResponseViewer"],
|
|
39
|
+
pro: PRO_FEATURES,
|
|
40
|
+
business: ALL_FEATURES,
|
|
41
|
+
enterprise: ALL_FEATURES
|
|
42
|
+
};
|
|
43
|
+
var HMAC_SECRET = "e50a657813a5ab9563050728a605b9ab58b911d5c1a9f48c6825f379a533ccd7685d11d01937d9f135776a0db3efeefe29b3e5282b27ede8cee93758f94f2d75";
|
|
44
|
+
var B32_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
|
|
45
|
+
function base32hexDecode(str) {
|
|
46
|
+
const upper = str.toUpperCase();
|
|
47
|
+
let bits = 0;
|
|
48
|
+
let value = 0;
|
|
49
|
+
const bytes = [];
|
|
50
|
+
for (let i = 0; i < upper.length; i++) {
|
|
51
|
+
const idx = B32_CHARS.indexOf(upper[i]);
|
|
52
|
+
if (idx === -1) return null;
|
|
53
|
+
value = value << 5 | idx;
|
|
54
|
+
bits += 5;
|
|
55
|
+
if (bits >= 8) {
|
|
56
|
+
bits -= 8;
|
|
57
|
+
bytes.push(value >>> bits & 255);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return new Uint8Array(bytes);
|
|
61
|
+
}
|
|
62
|
+
function parseLegacyKey(key) {
|
|
63
|
+
const parts = key.split("-");
|
|
64
|
+
if (parts.length !== 5) return null;
|
|
65
|
+
const [p1, p2, tierHex, expiryHex, hash] = parts;
|
|
66
|
+
if (p1 !== "FC" || p2 !== "PRO") return null;
|
|
67
|
+
if (!(tierHex in LEGACY_TIER_MAP)) return null;
|
|
68
|
+
if (!/^[0-9A-Fa-f]{8}$/.test(expiryHex)) return null;
|
|
69
|
+
if (!/^[0-9A-Fa-f]{8}$/.test(hash)) return null;
|
|
70
|
+
return { format: "legacy", tierHex, expiryHex, hash };
|
|
71
|
+
}
|
|
72
|
+
function parseOpaqueKey(key) {
|
|
73
|
+
const stripped = key.replace(/-/g, "");
|
|
74
|
+
if (!stripped.startsWith("FCPRO")) return null;
|
|
75
|
+
const encoded = stripped.slice(5);
|
|
76
|
+
const decoded = base32hexDecode(encoded);
|
|
77
|
+
if (!decoded || decoded.length < 17) return null;
|
|
78
|
+
const tier = decoded[0];
|
|
79
|
+
if (!(tier in TIER_MAP_NUMERIC)) return null;
|
|
80
|
+
const expiryTimestamp = decoded[1] << 24 | decoded[2] << 16 | decoded[3] << 8 | decoded[4];
|
|
81
|
+
const expiryUnsigned = expiryTimestamp >>> 0;
|
|
82
|
+
const nonce = decoded.slice(5, 9);
|
|
83
|
+
const signature = decoded.slice(9, 17);
|
|
84
|
+
return { format: "opaque", tier, expiryTimestamp: expiryUnsigned, nonce, signature };
|
|
85
|
+
}
|
|
86
|
+
function parseKey(key) {
|
|
87
|
+
if (!key || typeof key !== "string") return null;
|
|
88
|
+
if (key.startsWith("FCPRO-")) {
|
|
89
|
+
return parseOpaqueKey(key);
|
|
90
|
+
}
|
|
91
|
+
return parseLegacyKey(key);
|
|
92
|
+
}
|
|
93
|
+
async function computeHmacLegacy(tierHex, expiryHex) {
|
|
94
|
+
const encoder = new TextEncoder();
|
|
95
|
+
const keyData = encoder.encode(HMAC_SECRET);
|
|
96
|
+
const message = encoder.encode(`FC-PRO-${tierHex}-${expiryHex}`);
|
|
97
|
+
const cryptoKey = await crypto.subtle.importKey(
|
|
98
|
+
"raw",
|
|
99
|
+
keyData,
|
|
100
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
101
|
+
false,
|
|
102
|
+
["sign"]
|
|
103
|
+
);
|
|
104
|
+
const signature = await crypto.subtle.sign("HMAC", cryptoKey, message);
|
|
105
|
+
const hashBytes = new Uint8Array(signature).slice(0, 4);
|
|
106
|
+
return Array.from(hashBytes).map((b) => b.toString(16).padStart(2, "0")).join("").toUpperCase();
|
|
107
|
+
}
|
|
108
|
+
async function computeHmacOpaque(payload) {
|
|
109
|
+
const encoder = new TextEncoder();
|
|
110
|
+
const keyData = encoder.encode(HMAC_SECRET);
|
|
111
|
+
const cryptoKey = await crypto.subtle.importKey(
|
|
112
|
+
"raw",
|
|
113
|
+
keyData,
|
|
114
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
115
|
+
false,
|
|
116
|
+
["sign"]
|
|
117
|
+
);
|
|
118
|
+
const signature = await crypto.subtle.sign("HMAC", cryptoKey, payload);
|
|
119
|
+
return new Uint8Array(signature).slice(0, 8);
|
|
120
|
+
}
|
|
121
|
+
function isExpiredLegacy(expiryHex) {
|
|
122
|
+
const expiryTimestamp = parseInt(expiryHex, 16);
|
|
123
|
+
if (expiryTimestamp === 4294967295) return false;
|
|
124
|
+
return Date.now() / 1e3 > expiryTimestamp;
|
|
125
|
+
}
|
|
126
|
+
function isExpiredOpaque(expiryTimestamp) {
|
|
127
|
+
if (expiryTimestamp === 4294967295) return false;
|
|
128
|
+
return Date.now() / 1e3 > expiryTimestamp;
|
|
129
|
+
}
|
|
130
|
+
async function validateLicense(key) {
|
|
131
|
+
if (!key || typeof key !== "string") {
|
|
132
|
+
return { status: "invalid", tier: null };
|
|
133
|
+
}
|
|
134
|
+
const parsed = parseKey(key);
|
|
135
|
+
if (!parsed) {
|
|
136
|
+
return { status: "invalid", tier: null };
|
|
137
|
+
}
|
|
138
|
+
if (parsed.format === "opaque") {
|
|
139
|
+
const payload = new Uint8Array(9);
|
|
140
|
+
payload[0] = parsed.tier;
|
|
141
|
+
payload[1] = parsed.expiryTimestamp >>> 24 & 255;
|
|
142
|
+
payload[2] = parsed.expiryTimestamp >>> 16 & 255;
|
|
143
|
+
payload[3] = parsed.expiryTimestamp >>> 8 & 255;
|
|
144
|
+
payload[4] = parsed.expiryTimestamp & 255;
|
|
145
|
+
payload.set(parsed.nonce, 5);
|
|
146
|
+
const expectedSig = await computeHmacOpaque(payload);
|
|
147
|
+
let match = true;
|
|
148
|
+
for (let i = 0; i < 8; i++) {
|
|
149
|
+
if (parsed.signature[i] !== expectedSig[i]) {
|
|
150
|
+
match = false;
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (!match) {
|
|
155
|
+
return { status: "invalid", tier: null };
|
|
156
|
+
}
|
|
157
|
+
const tier2 = TIER_MAP_NUMERIC[parsed.tier];
|
|
158
|
+
if (!tier2) {
|
|
159
|
+
return { status: "invalid", tier: null };
|
|
160
|
+
}
|
|
161
|
+
if (isExpiredOpaque(parsed.expiryTimestamp)) {
|
|
162
|
+
return { status: "expired", tier: tier2 };
|
|
163
|
+
}
|
|
164
|
+
return { status: "valid", tier: tier2 };
|
|
165
|
+
}
|
|
166
|
+
const expectedHash = await computeHmacLegacy(parsed.tierHex, parsed.expiryHex);
|
|
167
|
+
if (parsed.hash.toUpperCase() !== expectedHash) {
|
|
168
|
+
return { status: "invalid", tier: null };
|
|
169
|
+
}
|
|
170
|
+
const tier = LEGACY_TIER_MAP[parsed.tierHex];
|
|
171
|
+
if (isExpiredLegacy(parsed.expiryHex)) {
|
|
172
|
+
return { status: "expired", tier };
|
|
173
|
+
}
|
|
174
|
+
return { status: "valid", tier };
|
|
175
|
+
}
|
|
176
|
+
function tierHasFeature(tier, featureName) {
|
|
177
|
+
return TIER_FEATURES[tier]?.includes(featureName) ?? false;
|
|
178
|
+
}
|
|
179
|
+
var DEV_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
180
|
+
"localhost",
|
|
181
|
+
"127.0.0.1",
|
|
182
|
+
"0.0.0.0",
|
|
183
|
+
"[::1]",
|
|
184
|
+
"::1"
|
|
185
|
+
]);
|
|
186
|
+
var DEV_HOSTNAME_PATTERNS = [
|
|
187
|
+
/^192\.168\.\d+\.\d+$/,
|
|
188
|
+
// local network
|
|
189
|
+
/^10\.\d+\.\d+\.\d+$/,
|
|
190
|
+
// local network
|
|
191
|
+
/^172\.(1[6-9]|2\d|3[01])\.\d+\.\d+$/
|
|
192
|
+
// local network
|
|
193
|
+
];
|
|
194
|
+
var PRODUCTION_HOST_SUFFIXES = [
|
|
195
|
+
".vercel.app",
|
|
196
|
+
".netlify.app",
|
|
197
|
+
".netlify.com",
|
|
198
|
+
".herokuapp.com",
|
|
199
|
+
".fly.dev",
|
|
200
|
+
".railway.app",
|
|
201
|
+
".render.com",
|
|
202
|
+
".onrender.com",
|
|
203
|
+
".pages.dev",
|
|
204
|
+
// Cloudflare Pages
|
|
205
|
+
".workers.dev",
|
|
206
|
+
// Cloudflare Workers
|
|
207
|
+
".azurewebsites.net",
|
|
208
|
+
".web.app",
|
|
209
|
+
// Firebase
|
|
210
|
+
".firebaseapp.com",
|
|
211
|
+
".amplifyapp.com",
|
|
212
|
+
".surge.sh",
|
|
213
|
+
".github.io",
|
|
214
|
+
".gitlab.io"
|
|
215
|
+
];
|
|
216
|
+
function isDevHostname(hostname) {
|
|
217
|
+
if (DEV_HOSTNAMES.has(hostname)) return true;
|
|
218
|
+
for (const pattern of DEV_HOSTNAME_PATTERNS) {
|
|
219
|
+
if (pattern.test(hostname)) return true;
|
|
220
|
+
}
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
function isKnownProductionHost(hostname) {
|
|
224
|
+
for (const suffix of PRODUCTION_HOST_SUFFIXES) {
|
|
225
|
+
if (hostname.endsWith(suffix)) return true;
|
|
226
|
+
}
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
function hasRealTLD(hostname) {
|
|
230
|
+
return /\.[a-z]{2,}$/i.test(hostname) && !isDevHostname(hostname);
|
|
231
|
+
}
|
|
232
|
+
function isProductionEnvironment() {
|
|
233
|
+
const _proc = typeof globalThis !== "undefined" ? globalThis.process : void 0;
|
|
234
|
+
if (_proc?.env) {
|
|
235
|
+
const nodeEnv = _proc.env.NODE_ENV;
|
|
236
|
+
if (nodeEnv === "production") return true;
|
|
237
|
+
if (nodeEnv === "development" || nodeEnv === "test") return false;
|
|
238
|
+
}
|
|
239
|
+
if (typeof window !== "undefined" && window.location) {
|
|
240
|
+
const { hostname, protocol, port } = window.location;
|
|
241
|
+
if (protocol === "file:") return false;
|
|
242
|
+
if (isDevHostname(hostname)) return false;
|
|
243
|
+
if (port && port !== "443" && port !== "80") return false;
|
|
244
|
+
if (isKnownProductionHost(hostname)) return true;
|
|
245
|
+
if (protocol === "https:" && hasRealTLD(hostname)) return true;
|
|
246
|
+
if (hasRealTLD(hostname)) return true;
|
|
247
|
+
}
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
var PING_URL = "https://squaredr.tech/api/license/ping";
|
|
251
|
+
var CACHE_KEY = "fcpro_lp";
|
|
252
|
+
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
253
|
+
function hashKey(key) {
|
|
254
|
+
let hash = 0;
|
|
255
|
+
for (let i = 0; i < key.length; i++) {
|
|
256
|
+
hash = (hash << 5) - hash + key.charCodeAt(i) | 0;
|
|
257
|
+
}
|
|
258
|
+
return Math.abs(hash).toString(36);
|
|
259
|
+
}
|
|
260
|
+
function cacheId(key) {
|
|
261
|
+
return `${CACHE_KEY}_${hashKey(key)}`;
|
|
262
|
+
}
|
|
263
|
+
function readCache(key) {
|
|
264
|
+
if (typeof window === "undefined" || !window.localStorage) return null;
|
|
265
|
+
try {
|
|
266
|
+
const raw = localStorage.getItem(cacheId(key));
|
|
267
|
+
if (!raw) return null;
|
|
268
|
+
const entry = JSON.parse(raw);
|
|
269
|
+
if (Date.now() - entry.ts > CACHE_TTL_MS) {
|
|
270
|
+
localStorage.removeItem(cacheId(key));
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
return entry;
|
|
274
|
+
} catch {
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
function writeCache(key, status, tier, reason = null) {
|
|
279
|
+
if (typeof window === "undefined" || !window.localStorage) return;
|
|
280
|
+
try {
|
|
281
|
+
const entry = { s: status, t: tier, r: reason, ts: Date.now() };
|
|
282
|
+
localStorage.setItem(cacheId(key), JSON.stringify(entry));
|
|
283
|
+
} catch {
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function getCachedPingResult(key) {
|
|
287
|
+
const cached = readCache(key);
|
|
288
|
+
if (!cached) return null;
|
|
289
|
+
return { status: cached.s, tier: cached.t, reason: cached.r || void 0 };
|
|
290
|
+
}
|
|
291
|
+
async function performPing(key) {
|
|
292
|
+
const cached = readCache(key);
|
|
293
|
+
if (cached) {
|
|
294
|
+
return { status: cached.s, tier: cached.t };
|
|
295
|
+
}
|
|
296
|
+
try {
|
|
297
|
+
const controller = new AbortController();
|
|
298
|
+
const timeout = setTimeout(() => controller.abort(), 1e4);
|
|
299
|
+
const res = await fetch(PING_URL, {
|
|
300
|
+
method: "POST",
|
|
301
|
+
headers: { "Content-Type": "application/json" },
|
|
302
|
+
body: JSON.stringify({ key }),
|
|
303
|
+
signal: controller.signal
|
|
304
|
+
});
|
|
305
|
+
clearTimeout(timeout);
|
|
306
|
+
if (!res.ok) return null;
|
|
307
|
+
const data = await res.json();
|
|
308
|
+
const tier = data.tier || null;
|
|
309
|
+
if (data.status === "active") {
|
|
310
|
+
writeCache(key, "valid", tier);
|
|
311
|
+
return { status: "valid", tier };
|
|
312
|
+
}
|
|
313
|
+
if (data.status === "revoked") {
|
|
314
|
+
writeCache(key, "revoked", null, data.reason);
|
|
315
|
+
return { status: "revoked", tier: null, reason: data.reason };
|
|
316
|
+
}
|
|
317
|
+
if (data.status === "expired") {
|
|
318
|
+
writeCache(key, "expired", tier);
|
|
319
|
+
return { status: "expired", tier };
|
|
320
|
+
}
|
|
321
|
+
if (data.status === "domain_mismatch") {
|
|
322
|
+
writeCache(key, "domain_mismatch", null, data.reason);
|
|
323
|
+
return { status: "domain_mismatch", tier: null, reason: data.reason };
|
|
324
|
+
}
|
|
325
|
+
return null;
|
|
326
|
+
} catch {
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
var defaultContext = { status: "validating", tier: null };
|
|
331
|
+
var LicenseCtx = react.createContext(defaultContext);
|
|
332
|
+
function FieldCraftProProvider({ licenseKey, children }) {
|
|
333
|
+
const [license, setLicense] = react.useState(defaultContext);
|
|
334
|
+
react.useEffect(() => {
|
|
335
|
+
let cancelled = false;
|
|
336
|
+
setLicense(defaultContext);
|
|
337
|
+
validateLicense(licenseKey).then((clientResult) => {
|
|
338
|
+
if (cancelled) return;
|
|
339
|
+
setLicense(clientResult);
|
|
340
|
+
if (clientResult.status !== "valid" || !isProductionEnvironment()) return;
|
|
341
|
+
const cached = getCachedPingResult(licenseKey);
|
|
342
|
+
if (cached) {
|
|
343
|
+
if (cached.status === "revoked" || cached.status === "domain_mismatch") {
|
|
344
|
+
setLicense({ status: cached.status, tier: null });
|
|
345
|
+
}
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
performPing(licenseKey).then((pingResult) => {
|
|
349
|
+
if (cancelled) return;
|
|
350
|
+
if (!pingResult) return;
|
|
351
|
+
if (pingResult.status === "revoked" || pingResult.status === "domain_mismatch") {
|
|
352
|
+
setLicense({ status: pingResult.status, tier: null });
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
return () => {
|
|
357
|
+
cancelled = true;
|
|
358
|
+
};
|
|
359
|
+
}, [licenseKey]);
|
|
360
|
+
return /* @__PURE__ */ jsxRuntime.jsx(LicenseCtx.Provider, { value: license, children });
|
|
361
|
+
}
|
|
362
|
+
function useLicense() {
|
|
363
|
+
return react.useContext(LicenseCtx);
|
|
364
|
+
}
|
|
365
|
+
function UnlicensedOverlay({ featureName, reason, children }) {
|
|
366
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "relative", minHeight: "200px" }, children: [
|
|
367
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { pointerEvents: "none", userSelect: "none", filter: "blur(2px)" }, children }),
|
|
368
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
369
|
+
"div",
|
|
370
|
+
{
|
|
371
|
+
style: {
|
|
372
|
+
position: "absolute",
|
|
373
|
+
inset: 0,
|
|
374
|
+
zIndex: 2147483647,
|
|
375
|
+
display: "flex",
|
|
376
|
+
flexDirection: "column",
|
|
377
|
+
alignItems: "center",
|
|
378
|
+
justifyContent: "center",
|
|
379
|
+
backgroundColor: "rgba(0, 0, 0, 0.75)",
|
|
380
|
+
backdropFilter: "blur(4px)",
|
|
381
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
382
|
+
padding: "32px"
|
|
383
|
+
},
|
|
384
|
+
children: [
|
|
385
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
386
|
+
"div",
|
|
387
|
+
{
|
|
388
|
+
style: {
|
|
389
|
+
position: "absolute",
|
|
390
|
+
inset: 0,
|
|
391
|
+
overflow: "hidden",
|
|
392
|
+
pointerEvents: "none",
|
|
393
|
+
zIndex: 0
|
|
394
|
+
},
|
|
395
|
+
children: Array.from({ length: 12 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
396
|
+
"div",
|
|
397
|
+
{
|
|
398
|
+
style: {
|
|
399
|
+
position: "absolute",
|
|
400
|
+
top: `${i * 80}px`,
|
|
401
|
+
left: "-50%",
|
|
402
|
+
right: "-50%",
|
|
403
|
+
textAlign: "center",
|
|
404
|
+
transform: "rotate(-30deg)",
|
|
405
|
+
fontSize: "18px",
|
|
406
|
+
fontWeight: 700,
|
|
407
|
+
color: "rgba(255, 255, 255, 0.06)",
|
|
408
|
+
letterSpacing: "8px",
|
|
409
|
+
textTransform: "uppercase",
|
|
410
|
+
whiteSpace: "nowrap",
|
|
411
|
+
userSelect: "none"
|
|
412
|
+
},
|
|
413
|
+
children: "UNLICENSED \u2022 FIELDCRAFT PRO \u2022 UNLICENSED \u2022 FIELDCRAFT PRO \u2022 UNLICENSED \u2022 FIELDCRAFT PRO"
|
|
414
|
+
},
|
|
415
|
+
i
|
|
416
|
+
))
|
|
417
|
+
}
|
|
418
|
+
),
|
|
419
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
420
|
+
"div",
|
|
421
|
+
{
|
|
422
|
+
style: {
|
|
423
|
+
position: "relative",
|
|
424
|
+
zIndex: 1,
|
|
425
|
+
textAlign: "center",
|
|
426
|
+
maxWidth: "420px"
|
|
427
|
+
},
|
|
428
|
+
children: [
|
|
429
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
430
|
+
"div",
|
|
431
|
+
{
|
|
432
|
+
style: {
|
|
433
|
+
width: "64px",
|
|
434
|
+
height: "64px",
|
|
435
|
+
margin: "0 auto 16px",
|
|
436
|
+
borderRadius: "50%",
|
|
437
|
+
backgroundColor: "rgba(239, 68, 68, 0.2)",
|
|
438
|
+
border: "2px solid rgba(239, 68, 68, 0.5)",
|
|
439
|
+
display: "flex",
|
|
440
|
+
alignItems: "center",
|
|
441
|
+
justifyContent: "center",
|
|
442
|
+
fontSize: "28px"
|
|
443
|
+
},
|
|
444
|
+
children: "\u{1F6E1}"
|
|
445
|
+
}
|
|
446
|
+
),
|
|
447
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
448
|
+
"div",
|
|
449
|
+
{
|
|
450
|
+
style: {
|
|
451
|
+
fontSize: "22px",
|
|
452
|
+
fontWeight: 700,
|
|
453
|
+
color: "#ffffff",
|
|
454
|
+
marginBottom: "8px",
|
|
455
|
+
letterSpacing: "-0.02em"
|
|
456
|
+
},
|
|
457
|
+
children: "License Required"
|
|
458
|
+
}
|
|
459
|
+
),
|
|
460
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
461
|
+
"div",
|
|
462
|
+
{
|
|
463
|
+
style: {
|
|
464
|
+
fontSize: "15px",
|
|
465
|
+
fontWeight: 600,
|
|
466
|
+
color: "#f87171",
|
|
467
|
+
marginBottom: "6px"
|
|
468
|
+
},
|
|
469
|
+
children: featureName
|
|
470
|
+
}
|
|
471
|
+
),
|
|
472
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
473
|
+
"div",
|
|
474
|
+
{
|
|
475
|
+
style: {
|
|
476
|
+
fontSize: "14px",
|
|
477
|
+
color: "#d1d5db",
|
|
478
|
+
marginBottom: "24px",
|
|
479
|
+
lineHeight: "1.5"
|
|
480
|
+
},
|
|
481
|
+
children: reason
|
|
482
|
+
}
|
|
483
|
+
),
|
|
484
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: "10px", justifyContent: "center", flexWrap: "wrap" }, children: [
|
|
485
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
486
|
+
"a",
|
|
487
|
+
{
|
|
488
|
+
href: "https://squaredr.tech/products/fieldcraft/admin-pro#pricing",
|
|
489
|
+
target: "_blank",
|
|
490
|
+
rel: "noopener noreferrer",
|
|
491
|
+
style: {
|
|
492
|
+
display: "inline-block",
|
|
493
|
+
padding: "12px 24px",
|
|
494
|
+
fontSize: "14px",
|
|
495
|
+
fontWeight: 600,
|
|
496
|
+
color: "#ffffff",
|
|
497
|
+
backgroundColor: "#2563eb",
|
|
498
|
+
borderRadius: "8px",
|
|
499
|
+
textDecoration: "none",
|
|
500
|
+
boxShadow: "0 4px 14px rgba(37, 99, 235, 0.4)"
|
|
501
|
+
},
|
|
502
|
+
children: "Get a License"
|
|
503
|
+
}
|
|
504
|
+
),
|
|
505
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
506
|
+
"a",
|
|
507
|
+
{
|
|
508
|
+
href: "https://discord.gg/zMxdu5UVW",
|
|
509
|
+
target: "_blank",
|
|
510
|
+
rel: "noopener noreferrer",
|
|
511
|
+
style: {
|
|
512
|
+
display: "inline-block",
|
|
513
|
+
padding: "12px 24px",
|
|
514
|
+
fontSize: "14px",
|
|
515
|
+
fontWeight: 600,
|
|
516
|
+
color: "#93c5fd",
|
|
517
|
+
backgroundColor: "rgba(37, 99, 235, 0.15)",
|
|
518
|
+
border: "1px solid rgba(37, 99, 235, 0.4)",
|
|
519
|
+
borderRadius: "8px",
|
|
520
|
+
textDecoration: "none"
|
|
521
|
+
},
|
|
522
|
+
children: "Join Discord"
|
|
523
|
+
}
|
|
524
|
+
)
|
|
525
|
+
] }),
|
|
526
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
527
|
+
"div",
|
|
528
|
+
{
|
|
529
|
+
style: {
|
|
530
|
+
fontSize: "12px",
|
|
531
|
+
color: "#6b7280",
|
|
532
|
+
marginTop: "16px"
|
|
533
|
+
},
|
|
534
|
+
children: [
|
|
535
|
+
"This component works freely in development.",
|
|
536
|
+
" ",
|
|
537
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
538
|
+
"a",
|
|
539
|
+
{
|
|
540
|
+
href: "https://squaredr.tech/products/fieldcraft/docs/pro/license",
|
|
541
|
+
target: "_blank",
|
|
542
|
+
rel: "noopener noreferrer",
|
|
543
|
+
style: { color: "#9ca3af", textDecoration: "underline" },
|
|
544
|
+
children: "Learn more"
|
|
545
|
+
}
|
|
546
|
+
)
|
|
547
|
+
]
|
|
548
|
+
}
|
|
549
|
+
)
|
|
550
|
+
]
|
|
551
|
+
}
|
|
552
|
+
)
|
|
553
|
+
]
|
|
554
|
+
}
|
|
555
|
+
)
|
|
556
|
+
] });
|
|
557
|
+
}
|
|
558
|
+
function requireLicense(Component2, featureName) {
|
|
559
|
+
function LicenseGated(props) {
|
|
560
|
+
const { status, tier } = useLicense();
|
|
561
|
+
const isProduction = isProductionEnvironment();
|
|
562
|
+
if (!isProduction) {
|
|
563
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Component2, { ...props });
|
|
564
|
+
}
|
|
565
|
+
if (status === "validating") {
|
|
566
|
+
return null;
|
|
567
|
+
}
|
|
568
|
+
const isLicensed = status === "valid" && tier != null && tierHasFeature(tier, featureName);
|
|
569
|
+
if (isLicensed) {
|
|
570
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Component2, { ...props });
|
|
571
|
+
}
|
|
572
|
+
let reason = "A valid license is required for production use.";
|
|
573
|
+
if (status === "invalid") {
|
|
574
|
+
reason = "Invalid license key. Please check your license key and try again.";
|
|
575
|
+
} else if (status === "expired") {
|
|
576
|
+
reason = "Your license has expired. Please renew to continue using this component in production.";
|
|
577
|
+
} else if (status === "revoked") {
|
|
578
|
+
reason = "This license key has been revoked. Please contact support or purchase a new license.";
|
|
579
|
+
} else if (status === "domain_mismatch") {
|
|
580
|
+
reason = "This license key is registered to a different domain. Each key can only be used on one production domain. Please purchase a new license for this domain.";
|
|
581
|
+
} else if (!tier || !tierHasFeature(tier, featureName)) {
|
|
582
|
+
reason = "Your license does not include this feature. Please upgrade your plan.";
|
|
583
|
+
}
|
|
584
|
+
return /* @__PURE__ */ jsxRuntime.jsx(UnlicensedOverlay, { featureName, reason, children: /* @__PURE__ */ jsxRuntime.jsx(Component2, { ...props }) });
|
|
585
|
+
}
|
|
586
|
+
LicenseGated.displayName = `requireLicense(${Component2.displayName || Component2.name || "Component"})`;
|
|
587
|
+
return LicenseGated;
|
|
588
|
+
}
|
|
14
589
|
var MAX_HISTORY = 50;
|
|
15
590
|
function useUndoRedo(currentSchema, setSchema) {
|
|
16
591
|
const historyRef = react.useRef([currentSchema]);
|
|
@@ -3122,7 +3697,7 @@ function FormBuilderInner(props) {
|
|
|
3122
3697
|
}
|
|
3123
3698
|
|
|
3124
3699
|
// src/form-builder/components/FormBuilderGated.tsx
|
|
3125
|
-
var FormBuilder =
|
|
3700
|
+
var FormBuilder = requireLicense(FormBuilderInner, "FormBuilder");
|
|
3126
3701
|
|
|
3127
3702
|
// src/form-builder/theme/presets.ts
|
|
3128
3703
|
var squaredrDarkPreset = {
|
|
@@ -4165,7 +4740,7 @@ function getAllQuestions2(schema) {
|
|
|
4165
4740
|
}
|
|
4166
4741
|
|
|
4167
4742
|
// src/response-viewer/ResponseViewer.tsx
|
|
4168
|
-
var ResponseViewer =
|
|
4743
|
+
var ResponseViewer = requireLicense(ResponseViewerInner, "ResponseViewer");
|
|
4169
4744
|
|
|
4170
4745
|
// src/theme-editor/preview-schema.ts
|
|
4171
4746
|
var PREVIEW_SCHEMA = {
|
|
@@ -4566,7 +5141,7 @@ function ThemeEditorInner({
|
|
|
4566
5141
|
}
|
|
4567
5142
|
|
|
4568
5143
|
// src/theme-editor/ThemeEditor.tsx
|
|
4569
|
-
var ThemeEditor =
|
|
5144
|
+
var ThemeEditor = requireLicense(ThemeEditorInner, "ThemeEditor");
|
|
4570
5145
|
|
|
4571
5146
|
// src/index.ts
|
|
4572
5147
|
if (typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" && globalThis.process.env?.NODE_ENV !== "production") {
|
|
@@ -4589,32 +5164,9 @@ Need a license? \u2192 https://squaredr.tech/products/fieldcraft/admin-pro#prici
|
|
|
4589
5164
|
);
|
|
4590
5165
|
}
|
|
4591
5166
|
|
|
4592
|
-
Object.defineProperty(exports, "FieldCraftProProvider", {
|
|
4593
|
-
enumerable: true,
|
|
4594
|
-
get: function () { return fieldcraftProLicense.FieldCraftProProvider; }
|
|
4595
|
-
});
|
|
4596
|
-
Object.defineProperty(exports, "UnlicensedOverlay", {
|
|
4597
|
-
enumerable: true,
|
|
4598
|
-
get: function () { return fieldcraftProLicense.UnlicensedOverlay; }
|
|
4599
|
-
});
|
|
4600
|
-
Object.defineProperty(exports, "isProductionEnvironment", {
|
|
4601
|
-
enumerable: true,
|
|
4602
|
-
get: function () { return fieldcraftProLicense.isProductionEnvironment; }
|
|
4603
|
-
});
|
|
4604
|
-
Object.defineProperty(exports, "requireLicense", {
|
|
4605
|
-
enumerable: true,
|
|
4606
|
-
get: function () { return fieldcraftProLicense.requireLicense; }
|
|
4607
|
-
});
|
|
4608
|
-
Object.defineProperty(exports, "useLicense", {
|
|
4609
|
-
enumerable: true,
|
|
4610
|
-
get: function () { return fieldcraftProLicense.useLicense; }
|
|
4611
|
-
});
|
|
4612
|
-
Object.defineProperty(exports, "validateLicense", {
|
|
4613
|
-
enumerable: true,
|
|
4614
|
-
get: function () { return fieldcraftProLicense.validateLicense; }
|
|
4615
|
-
});
|
|
4616
5167
|
exports.DEFAULT_PALETTE = DEFAULT_PALETTE;
|
|
4617
5168
|
exports.DEFAULT_SCHEMA = DEFAULT_SCHEMA;
|
|
5169
|
+
exports.FieldCraftProProvider = FieldCraftProProvider;
|
|
4618
5170
|
exports.FormBuilder = FormBuilder;
|
|
4619
5171
|
exports.FormBuilderThemeProvider = FormBuilderThemeProvider;
|
|
4620
5172
|
exports.PREVIEW_SCHEMA = PREVIEW_SCHEMA;
|
|
@@ -4622,6 +5174,7 @@ exports.QUESTION_TYPE_INFO = QUESTION_TYPE_INFO;
|
|
|
4622
5174
|
exports.ResponseViewer = ResponseViewer;
|
|
4623
5175
|
exports.ThemeEditor = ThemeEditor;
|
|
4624
5176
|
exports.ThemeEditorInner = ThemeEditorInner;
|
|
5177
|
+
exports.UnlicensedOverlay = UnlicensedOverlay;
|
|
4625
5178
|
exports.addOption = addOption;
|
|
4626
5179
|
exports.addQuestion = addQuestion;
|
|
4627
5180
|
exports.addSection = addSection;
|
|
@@ -4635,12 +5188,14 @@ exports.generateId = generateId;
|
|
|
4635
5188
|
exports.generateOptionId = generateOptionId;
|
|
4636
5189
|
exports.generateQuestionId = generateQuestionId;
|
|
4637
5190
|
exports.generateSectionId = generateSectionId;
|
|
5191
|
+
exports.isProductionEnvironment = isProductionEnvironment;
|
|
4638
5192
|
exports.moveOption = moveOption;
|
|
4639
5193
|
exports.moveQuestion = moveQuestion;
|
|
4640
5194
|
exports.moveSection = moveSection;
|
|
4641
5195
|
exports.removeOption = removeOption;
|
|
4642
5196
|
exports.removeQuestion = removeQuestion;
|
|
4643
5197
|
exports.removeSection = removeSection;
|
|
5198
|
+
exports.requireLicense = requireLicense;
|
|
4644
5199
|
exports.squaredrDarkPreset = squaredrDarkPreset;
|
|
4645
5200
|
exports.updateOption = updateOption;
|
|
4646
5201
|
exports.updateQuestion = updateQuestion;
|
|
@@ -4648,4 +5203,6 @@ exports.updateSection = updateSection;
|
|
|
4648
5203
|
exports.useBuilderState = useBuilderState;
|
|
4649
5204
|
exports.useBuilderTheme = useBuilderTheme;
|
|
4650
5205
|
exports.useDragDrop = useDragDrop;
|
|
5206
|
+
exports.useLicense = useLicense;
|
|
4651
5207
|
exports.useUndoRedo = useUndoRedo;
|
|
5208
|
+
exports.validateLicense = validateLicense;
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export { DEFAULT_PALETTE, DEFAULT_SCHEMA, FormBuilder, FormBuilderThemeProvider, QUESTION_TYPE_INFO, addOption, addQuestion, addSection, cleanPreset, duplicateQuestion, duplicateSection, findQuestion, findSection, generateId, generateOptionId, generateQuestionId, generateSectionId, moveOption, moveQuestion, moveSection, removeOption, removeQuestion, removeSection, squaredrDarkPreset, updateOption, updateQuestion, updateSection, useBuilderState, useBuilderTheme, useDragDrop, useUndoRedo } from './chunk-
|
|
2
|
-
export { ResponseViewer } from './chunk-
|
|
1
|
+
export { DEFAULT_PALETTE, DEFAULT_SCHEMA, FormBuilder, FormBuilderThemeProvider, QUESTION_TYPE_INFO, addOption, addQuestion, addSection, cleanPreset, duplicateQuestion, duplicateSection, findQuestion, findSection, generateId, generateOptionId, generateQuestionId, generateSectionId, moveOption, moveQuestion, moveSection, removeOption, removeQuestion, removeSection, squaredrDarkPreset, updateOption, updateQuestion, updateSection, useBuilderState, useBuilderTheme, useDragDrop, useUndoRedo } from './chunk-CJBC3KWB.mjs';
|
|
2
|
+
export { ResponseViewer } from './chunk-RSU3X25P.mjs';
|
|
3
3
|
export { cn } from './chunk-QQ4JZGTD.mjs';
|
|
4
|
-
export { PREVIEW_SCHEMA, ThemeEditor, ThemeEditorInner } from './chunk-
|
|
5
|
-
export { FieldCraftProProvider, UnlicensedOverlay, isProductionEnvironment, requireLicense, useLicense, validateLicense } from '
|
|
4
|
+
export { PREVIEW_SCHEMA, ThemeEditor, ThemeEditorInner } from './chunk-7LQW5QYT.mjs';
|
|
5
|
+
export { FieldCraftProProvider, UnlicensedOverlay, isProductionEnvironment, requireLicense, useLicense, validateLicense } from './chunk-VECQKSWS.mjs';
|
|
6
6
|
|
|
7
|
+
// src/index.ts
|
|
7
8
|
if (typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" && globalThis.process.env?.NODE_ENV !== "production") {
|
|
8
9
|
const _fc_banner = `
|
|
9
10
|
%c FieldCraft Pro %c v1.0.1
|