@embeddables/cli 0.6.7 → 0.6.9
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 +14 -0
- package/dist/commands/branch.d.ts.map +1 -1
- package/dist/commands/branch.js +6 -1
- package/dist/commands/build.d.ts.map +1 -1
- package/dist/commands/build.js +6 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +6 -1
- package/dist/commands/experiments-connect.d.ts.map +1 -1
- package/dist/commands/experiments-connect.js +7 -2
- package/dist/commands/pull.d.ts.map +1 -1
- package/dist/commands/pull.js +6 -1
- package/dist/commands/save.d.ts +22 -0
- package/dist/commands/save.d.ts.map +1 -1
- package/dist/commands/save.js +71 -5
- package/dist/compiler/parsePage.js +27 -6
- package/dist/compiler/reverse.d.ts.map +1 -1
- package/dist/compiler/reverse.js +14 -5
- package/dist/helpers/TEMP helpers file.d.ts +1 -0
- package/dist/helpers/TEMP helpers file.d.ts.map +1 -0
- package/dist/helpers/TEMP helpers file.js +1 -0
- package/dist/helpers/json.d.ts +47 -0
- package/dist/helpers/json.d.ts.map +1 -0
- package/dist/helpers/json.js +622 -0
- package/dist/helpers/utils.d.ts +13 -0
- package/dist/helpers/utils.d.ts.map +1 -0
- package/dist/helpers/utils.js +28 -0
- package/dist/logger.d.ts +10 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +17 -0
- package/dist/proxy/server.d.ts.map +1 -1
- package/dist/proxy/server.js +10 -4
- package/dist/stdout.d.ts +17 -0
- package/dist/stdout.d.ts.map +1 -0
- package/dist/stdout.js +23 -0
- package/dist/types-builder.d.ts +1 -1
- package/dist/types-builder.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,6 +51,20 @@ embeddables/
|
|
|
51
51
|
.generated/ # Compiled JSON output
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
+
## Upgrading the CLI
|
|
55
|
+
|
|
56
|
+
When a new CLI version is released, update with:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
embeddables upgrade
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
You can check your currently installed version with:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
embeddables -v
|
|
66
|
+
```
|
|
67
|
+
|
|
54
68
|
## Commands
|
|
55
69
|
|
|
56
70
|
### `embeddables init`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"branch.d.ts","sourceRoot":"","sources":["../../src/commands/branch.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"branch.d.ts","sourceRoot":"","sources":["../../src/commands/branch.ts"],"names":[],"mappings":"AAMA,wBAAsB,SAAS,CAAC,IAAI,EAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,iBAwDpD"}
|
package/dist/commands/branch.js
CHANGED
|
@@ -2,6 +2,7 @@ import pc from 'picocolors';
|
|
|
2
2
|
import { isLoggedIn } from '../auth/index.js';
|
|
3
3
|
import { runPull } from './pull.js';
|
|
4
4
|
import { promptForLocalEmbeddable, fetchBranches, promptForBranch } from '../prompts/index.js';
|
|
5
|
+
import { inferEmbeddableFromCwd } from '../helpers/utils.js';
|
|
5
6
|
export async function runBranch(opts) {
|
|
6
7
|
// Check login status
|
|
7
8
|
if (!isLoggedIn()) {
|
|
@@ -10,7 +11,11 @@ export async function runBranch(opts) {
|
|
|
10
11
|
process.exit(1);
|
|
11
12
|
}
|
|
12
13
|
// Get embeddable ID
|
|
13
|
-
|
|
14
|
+
const inferred = inferEmbeddableFromCwd();
|
|
15
|
+
let embeddableId = opts.id ?? inferred?.embeddableId;
|
|
16
|
+
if (inferred && !opts.id && embeddableId) {
|
|
17
|
+
process.chdir(inferred.projectRoot);
|
|
18
|
+
}
|
|
14
19
|
if (!embeddableId) {
|
|
15
20
|
const selected = await promptForLocalEmbeddable();
|
|
16
21
|
if (!selected) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAMA,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IACnC,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,WAAW,EAAE,UAAU,GAAG,QAAQ,CAAA;CACnC,iBAiCA"}
|
package/dist/commands/build.js
CHANGED
|
@@ -2,8 +2,13 @@ import path from 'node:path';
|
|
|
2
2
|
import { compileAllPages } from '../compiler/index.js';
|
|
3
3
|
import { formatError } from '../compiler/errors.js';
|
|
4
4
|
import { promptForLocalEmbeddable } from '../prompts/index.js';
|
|
5
|
+
import { inferEmbeddableFromCwd } from '../helpers/utils.js';
|
|
5
6
|
export async function runBuild(opts) {
|
|
6
|
-
|
|
7
|
+
const inferred = inferEmbeddableFromCwd();
|
|
8
|
+
let embeddableId = opts.id ?? inferred?.embeddableId;
|
|
9
|
+
if (inferred && !opts.id && embeddableId) {
|
|
10
|
+
process.chdir(inferred.projectRoot);
|
|
11
|
+
}
|
|
7
12
|
if (!embeddableId) {
|
|
8
13
|
const selected = await promptForLocalEmbeddable({
|
|
9
14
|
message: 'Select an embeddable to build:',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAoHA,wBAAsB,MAAM,CAAC,IAAI,EAAE;IACjC,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,UAAU,GAAG,QAAQ,CAAA;CACnC,iBAkHA"}
|
package/dist/commands/dev.js
CHANGED
|
@@ -7,6 +7,7 @@ import prompts from 'prompts';
|
|
|
7
7
|
import { compileAllPages } from '../compiler/index.js';
|
|
8
8
|
import { startProxyServer } from '../proxy/server.js';
|
|
9
9
|
import { formatError } from '../compiler/errors.js';
|
|
10
|
+
import { inferEmbeddableFromCwd } from '../helpers/utils.js';
|
|
10
11
|
/**
|
|
11
12
|
* Check whether a port is available by attempting to listen on it.
|
|
12
13
|
*/
|
|
@@ -92,7 +93,11 @@ async function promptForEmbeddable() {
|
|
|
92
93
|
return response.id || null;
|
|
93
94
|
}
|
|
94
95
|
export async function runDev(opts) {
|
|
95
|
-
|
|
96
|
+
const inferred = inferEmbeddableFromCwd();
|
|
97
|
+
let embeddableId = opts.id ?? inferred?.embeddableId;
|
|
98
|
+
if (inferred && !opts.id && embeddableId) {
|
|
99
|
+
process.chdir(inferred.projectRoot);
|
|
100
|
+
}
|
|
96
101
|
if (!embeddableId) {
|
|
97
102
|
const selected = await promptForEmbeddable();
|
|
98
103
|
if (!selected) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"experiments-connect.d.ts","sourceRoot":"","sources":["../../src/commands/experiments-connect.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"experiments-connect.d.ts","sourceRoot":"","sources":["../../src/commands/experiments-connect.ts"],"names":[],"mappings":"AAaA,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB,iBAcA"}
|
|
@@ -4,6 +4,7 @@ import pc from 'picocolors';
|
|
|
4
4
|
import { isLoggedIn } from '../auth/index.js';
|
|
5
5
|
import { getProjectId, writeProjectConfig } from '../config/index.js';
|
|
6
6
|
import { promptForProject, promptForLocalEmbeddable, promptForExperiment, } from '../prompts/index.js';
|
|
7
|
+
import { inferEmbeddableFromCwd } from '../helpers/utils.js';
|
|
7
8
|
export async function runExperimentsConnect(opts) {
|
|
8
9
|
try {
|
|
9
10
|
await runExperimentsConnectInner(opts);
|
|
@@ -46,8 +47,12 @@ async function runExperimentsConnectInner(opts) {
|
|
|
46
47
|
console.log(pc.green('✓ Saved project to embeddables.json'));
|
|
47
48
|
console.log('');
|
|
48
49
|
}
|
|
49
|
-
// 4. Get embeddable ID
|
|
50
|
-
|
|
50
|
+
// 4. Get embeddable ID (from option, cwd inference, or interactive prompt)
|
|
51
|
+
const inferred = inferEmbeddableFromCwd();
|
|
52
|
+
let embeddableId = opts.id ?? inferred?.embeddableId;
|
|
53
|
+
if (inferred && !opts.id && embeddableId) {
|
|
54
|
+
process.chdir(inferred.projectRoot);
|
|
55
|
+
}
|
|
51
56
|
if (!embeddableId) {
|
|
52
57
|
const selected = await promptForLocalEmbeddable({
|
|
53
58
|
message: 'Select an embeddable to connect the experiment to:',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AAgHA,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE,cAAc,iBAiQjD"}
|
package/dist/commands/pull.js
CHANGED
|
@@ -6,6 +6,7 @@ import { reverseCompile } from '../compiler/reverse.js';
|
|
|
6
6
|
import { getAccessToken, isLoggedIn } from '../auth/index.js';
|
|
7
7
|
import { getProjectId, writeProjectConfig } from '../config/index.js';
|
|
8
8
|
import { promptForProject, promptForEmbeddable, fetchEmbeddableMetadata } from '../prompts/index.js';
|
|
9
|
+
import { inferEmbeddableFromCwd } from '../helpers/utils.js';
|
|
9
10
|
/**
|
|
10
11
|
* Normalize custom_validation_function strings so literal "\\n" (backslash-n) becomes real newline.
|
|
11
12
|
* The API sometimes returns these double-escaped; dataOutputs/computedFields code is written
|
|
@@ -108,7 +109,11 @@ function writePullMetadataToConfig(embeddableId, version, branch, branchName) {
|
|
|
108
109
|
}
|
|
109
110
|
}
|
|
110
111
|
export async function runPull(opts) {
|
|
111
|
-
|
|
112
|
+
const inferred = inferEmbeddableFromCwd();
|
|
113
|
+
let embeddableId = opts.id ?? inferred?.embeddableId;
|
|
114
|
+
if (inferred && !opts.id && embeddableId) {
|
|
115
|
+
process.chdir(inferred.projectRoot);
|
|
116
|
+
}
|
|
112
117
|
// If no ID provided, try to get it interactively
|
|
113
118
|
if (!embeddableId) {
|
|
114
119
|
if (!isLoggedIn()) {
|
package/dist/commands/save.d.ts
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
import type { HistoryCommand } from '../types-builder.js';
|
|
2
|
+
export type EditHistoryDescription = {
|
|
3
|
+
origin: string;
|
|
4
|
+
description: string;
|
|
5
|
+
} | {
|
|
6
|
+
overflowed: boolean;
|
|
7
|
+
};
|
|
8
|
+
export type SaveEmbeddableVersionParams = {
|
|
9
|
+
embeddableId: string;
|
|
10
|
+
jsonString: string;
|
|
11
|
+
userId: string;
|
|
12
|
+
projectId: string;
|
|
13
|
+
label?: string;
|
|
14
|
+
fromVersionNumber: number;
|
|
15
|
+
editHistoryLength?: number;
|
|
16
|
+
editHistoryDescriptions?: EditHistoryDescription[];
|
|
17
|
+
workingDraftId?: string;
|
|
18
|
+
editHistoryStorageKey?: string;
|
|
19
|
+
editHistory?: HistoryCommand[];
|
|
20
|
+
branchId?: string | null;
|
|
21
|
+
branchMergedId?: string | null;
|
|
22
|
+
};
|
|
1
23
|
export declare function runSave(opts: {
|
|
2
24
|
id?: string;
|
|
3
25
|
label?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../../src/commands/save.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"save.d.ts","sourceRoot":"","sources":["../../src/commands/save.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAGV,cAAc,EACf,MAAM,qBAAqB,CAAA;AAgC5B,MAAM,MAAM,sBAAsB,GAC9B;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,UAAU,EAAE,OAAO,CAAA;CAAE,CAAA;AAE3B,MAAM,MAAM,2BAA2B,GAAG;IACxC,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iBAAiB,EAAE,MAAM,CAAA;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,uBAAuB,CAAC,EAAE,sBAAsB,EAAE,CAAA;IAClD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,WAAW,CAAC,EAAE,cAAc,EAAE,CAAA;IAC9B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B,CAAA;AAkND,wBAAsB,OAAO,CAAC,IAAI,EAAE;IAClC,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,iBAoBA"}
|
package/dist/commands/save.js
CHANGED
|
@@ -8,6 +8,8 @@ import { compileAllPages } from '../compiler/index.js';
|
|
|
8
8
|
import { formatError } from '../compiler/errors.js';
|
|
9
9
|
import { promptForLocalEmbeddable, promptForProject } from '../prompts/index.js';
|
|
10
10
|
import { WEB_APP_BASE_URL } from '../constants.js';
|
|
11
|
+
import { translateJsonDiffToEditCommands } from '../helpers/json.js';
|
|
12
|
+
import { generateId, inferEmbeddableFromCwd } from '../helpers/utils.js';
|
|
11
13
|
/** Error with optional gray detail line (hint/next step) for the user. */
|
|
12
14
|
class SaveError extends Error {
|
|
13
15
|
detail;
|
|
@@ -90,7 +92,9 @@ function getBranchFromConfig(embeddableId) {
|
|
|
90
92
|
}
|
|
91
93
|
/** Slug for branch name/id for versioned filenames (e.g. "my branch" -> "my_branch"). */
|
|
92
94
|
function slugForBranch(nameOrId) {
|
|
93
|
-
return String(nameOrId)
|
|
95
|
+
return (String(nameOrId)
|
|
96
|
+
.replace(/[^a-zA-Z0-9_.-]/g, '_')
|
|
97
|
+
.replace(/_+/g, '_') || 'main');
|
|
94
98
|
}
|
|
95
99
|
/** Get branch slug from config (_branch_name preferred, else _branch_id, else main). */
|
|
96
100
|
function getBranchSlugFromConfig(embeddableId) {
|
|
@@ -221,8 +225,12 @@ async function runSaveInner(opts) {
|
|
|
221
225
|
console.log(pc.gray('Run "embeddables login" to re-authenticate.'));
|
|
222
226
|
process.exit(1);
|
|
223
227
|
}
|
|
224
|
-
// 3. Get embeddable ID (from option or interactive prompt)
|
|
225
|
-
|
|
228
|
+
// 3. Get embeddable ID (from option, cwd inference, or interactive prompt)
|
|
229
|
+
const inferred = inferEmbeddableFromCwd();
|
|
230
|
+
let embeddableId = opts.id ?? inferred?.embeddableId;
|
|
231
|
+
if (inferred && !opts.id && embeddableId) {
|
|
232
|
+
process.chdir(inferred.projectRoot);
|
|
233
|
+
}
|
|
226
234
|
if (!embeddableId) {
|
|
227
235
|
const selected = await promptForLocalEmbeddable({
|
|
228
236
|
message: 'Select an embeddable to save:',
|
|
@@ -320,10 +328,11 @@ async function runSaveInner(opts) {
|
|
|
320
328
|
fromVersionNumber = detectedVersion;
|
|
321
329
|
}
|
|
322
330
|
// 7b. Check for other users' drafts on this version; warn and optionally abort
|
|
331
|
+
let currentUserId = null;
|
|
323
332
|
const supabase = await getAuthenticatedSupabaseClient();
|
|
324
333
|
if (supabase) {
|
|
325
334
|
const { data: { user }, } = await supabase.auth.getUser();
|
|
326
|
-
|
|
335
|
+
currentUserId = user?.id ?? null;
|
|
327
336
|
if (currentUserId) {
|
|
328
337
|
const branchIdForDrafts = effectiveBranch ?? null;
|
|
329
338
|
const otherDrafts = await fetchOtherUsersDrafts(supabase, embeddableId, fromVersionNumber, branchIdForDrafts, currentUserId);
|
|
@@ -331,7 +340,9 @@ async function runSaveInner(opts) {
|
|
|
331
340
|
const names = otherDrafts
|
|
332
341
|
.map((d) => d.author_name?.trim() || d.author_id || 'Someone')
|
|
333
342
|
.filter((n, i, a) => a.indexOf(n) === i);
|
|
334
|
-
const namesText = names.length === 1
|
|
343
|
+
const namesText = names.length === 1
|
|
344
|
+
? names[0]
|
|
345
|
+
: `${names.slice(0, -1).join(', ')} and ${names[names.length - 1]}`;
|
|
335
346
|
console.log('');
|
|
336
347
|
console.warn(pc.yellow(`⚠ ${namesText} ${names.length === 1 ? 'has' : 'have'} unsaved edits on version ${fromVersionNumber}. Saving may cause conflicts.`));
|
|
337
348
|
const { proceed } = await prompts({
|
|
@@ -354,11 +365,44 @@ async function runSaveInner(opts) {
|
|
|
354
365
|
}
|
|
355
366
|
// 8. POST to save-version API
|
|
356
367
|
console.log(pc.cyan(`Saving embeddable (based on v${fromVersionNumber})...`));
|
|
368
|
+
// Resolve current user id (required by API)
|
|
369
|
+
if (!currentUserId && supabase) {
|
|
370
|
+
const { data: { user }, } = await supabase.auth.getUser();
|
|
371
|
+
currentUserId = user?.id ?? null;
|
|
372
|
+
}
|
|
373
|
+
if (!currentUserId) {
|
|
374
|
+
throw new SaveError('You must be logged in to save.', 'Run "embeddables login" to authenticate.');
|
|
375
|
+
}
|
|
376
|
+
// Previous version JSON: from versioned snapshot file, or {} if not found (e.g. --from-version without pull)
|
|
377
|
+
const previousVersionPath = path.join(generatedDir, `embeddable-${getBranchSlugFromConfig(embeddableId)}@${fromVersionNumber}.json`);
|
|
378
|
+
const legacyVersionPath = path.join(generatedDir, `embeddable-v${fromVersionNumber}.json`);
|
|
379
|
+
const previousJsonContent = fs.existsSync(previousVersionPath)
|
|
380
|
+
? fs.readFileSync(previousVersionPath, 'utf8')
|
|
381
|
+
: fs.existsSync(legacyVersionPath)
|
|
382
|
+
? fs.readFileSync(legacyVersionPath, 'utf8')
|
|
383
|
+
: '{}';
|
|
384
|
+
const commands = translateJsonDiffToEditCommands({
|
|
385
|
+
previousObject: JSON.parse(previousJsonContent),
|
|
386
|
+
currentObject: JSON.parse(jsonContent),
|
|
387
|
+
basePath: [],
|
|
388
|
+
});
|
|
357
389
|
const body = {
|
|
390
|
+
userId: currentUserId,
|
|
358
391
|
embeddableId,
|
|
359
392
|
jsonString: JSON.stringify(embeddableJson),
|
|
360
393
|
projectId,
|
|
361
394
|
fromVersionNumber,
|
|
395
|
+
editHistoryLength: 1,
|
|
396
|
+
editHistoryDescriptions: [{ origin: 'CLI', description: 'Saved version from CLI' }],
|
|
397
|
+
editHistory: [
|
|
398
|
+
setMultipleFlowUpdates({
|
|
399
|
+
commands,
|
|
400
|
+
metadata: {
|
|
401
|
+
description: 'Saved version from CLI',
|
|
402
|
+
trigger: { origin: 'CLI', editor: 'CLI' },
|
|
403
|
+
},
|
|
404
|
+
}),
|
|
405
|
+
],
|
|
362
406
|
};
|
|
363
407
|
if (opts.label) {
|
|
364
408
|
body.label = opts.label;
|
|
@@ -476,3 +520,25 @@ async function runSaveInner(opts) {
|
|
|
476
520
|
fs.writeFileSync(versionedPath, jsonContent, 'utf8');
|
|
477
521
|
console.log(pc.cyan(`✓ Saved version file to ${versionedPath}`));
|
|
478
522
|
}
|
|
523
|
+
function setMultipleFlowUpdates({ commands, metadata, }) {
|
|
524
|
+
const type = 'set_multiple_embeddable_updates';
|
|
525
|
+
const simpleCommandTypes = {
|
|
526
|
+
add: 'add_embeddable_property',
|
|
527
|
+
remove: 'remove_embeddable_property',
|
|
528
|
+
set: 'update_embeddable_property',
|
|
529
|
+
move: 'move_embeddable_property',
|
|
530
|
+
};
|
|
531
|
+
//* Map the commands to the correct type and data
|
|
532
|
+
const mappedCommands = commands.map((command) => ({
|
|
533
|
+
type: Object.keys(simpleCommandTypes).includes(command.type)
|
|
534
|
+
? simpleCommandTypes[command.type]
|
|
535
|
+
: command.type,
|
|
536
|
+
data: command.data,
|
|
537
|
+
}));
|
|
538
|
+
return {
|
|
539
|
+
id: generateId('edit'),
|
|
540
|
+
type,
|
|
541
|
+
data: { commands: mappedCommands },
|
|
542
|
+
metadata,
|
|
543
|
+
};
|
|
544
|
+
}
|
|
@@ -426,6 +426,10 @@ function attrsToProps(attrs, constEnv, filePath, validationFunctionSource) {
|
|
|
426
426
|
}
|
|
427
427
|
throw new CompileError(`Unsupported JSX attribute value for "${name}".`, loc(filePath, a));
|
|
428
428
|
}
|
|
429
|
+
// When validation_formula is not "custom", custom_validation_function is ignored and omitted (removed on save).
|
|
430
|
+
if (out.validation_formula != null && out.validation_formula !== 'custom' && 'custom_validation_function' in out) {
|
|
431
|
+
delete out.custom_validation_function;
|
|
432
|
+
}
|
|
429
433
|
return out;
|
|
430
434
|
}
|
|
431
435
|
function getJsxTagName(n) {
|
|
@@ -506,25 +510,42 @@ const HTML_VOID_ELEMENTS = new Set([
|
|
|
506
510
|
'track',
|
|
507
511
|
'wbr',
|
|
508
512
|
]);
|
|
513
|
+
/**
|
|
514
|
+
* Map React/JSX attribute names to HTML attribute names so serialized HTML
|
|
515
|
+
* uses valid attributes (e.g. class for CSS, not className).
|
|
516
|
+
*/
|
|
517
|
+
function jsxAttrNameToHTMLAttrName(jsxName) {
|
|
518
|
+
switch (jsxName) {
|
|
519
|
+
case 'className':
|
|
520
|
+
return 'class';
|
|
521
|
+
case 'htmlFor':
|
|
522
|
+
return 'for';
|
|
523
|
+
case 'tabIndex':
|
|
524
|
+
return 'tabindex';
|
|
525
|
+
default:
|
|
526
|
+
return jsxName;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
509
529
|
/**
|
|
510
530
|
* Converts a JSX element to HTML string.
|
|
511
531
|
*/
|
|
512
532
|
function jsxElementToHTML(el, constEnv, filePath) {
|
|
513
533
|
const opening = el.openingElement;
|
|
514
534
|
const tagName = getJsxTagName(opening.name);
|
|
515
|
-
// Build attributes string
|
|
535
|
+
// Build attributes string (use HTML attribute names so class selectors work)
|
|
516
536
|
const attrs = [];
|
|
517
537
|
for (const attr of opening.attributes) {
|
|
518
538
|
if (attr.type === 'JSXAttribute') {
|
|
519
539
|
const name = attr.name.type === 'JSXIdentifier'
|
|
520
540
|
? attr.name.name
|
|
521
541
|
: `${attr.name.namespace.name}:${attr.name.name.name}`;
|
|
542
|
+
const htmlName = jsxAttrNameToHTMLAttrName(name);
|
|
522
543
|
if (!attr.value) {
|
|
523
544
|
// Boolean attribute
|
|
524
|
-
attrs.push(
|
|
545
|
+
attrs.push(htmlName);
|
|
525
546
|
}
|
|
526
547
|
else if (attr.value.type === 'StringLiteral') {
|
|
527
|
-
attrs.push(`${
|
|
548
|
+
attrs.push(`${htmlName}="${escapeHTMLAttribute(attr.value.value)}"`);
|
|
528
549
|
}
|
|
529
550
|
else if (attr.value.type === 'JSXExpressionContainer') {
|
|
530
551
|
try {
|
|
@@ -532,13 +553,13 @@ function jsxElementToHTML(el, constEnv, filePath) {
|
|
|
532
553
|
if (name === 'style' && typeof value === 'object' && value !== null) {
|
|
533
554
|
// Convert style object to CSS string
|
|
534
555
|
const cssString = styleObjectToCSS(value);
|
|
535
|
-
attrs.push(`${
|
|
556
|
+
attrs.push(`${htmlName}="${escapeHTMLAttribute(cssString)}"`);
|
|
536
557
|
}
|
|
537
558
|
else if (typeof value === 'string') {
|
|
538
|
-
attrs.push(`${
|
|
559
|
+
attrs.push(`${htmlName}="${escapeHTMLAttribute(value)}"`);
|
|
539
560
|
}
|
|
540
561
|
else if (typeof value === 'number' || typeof value === 'boolean') {
|
|
541
|
-
attrs.push(`${
|
|
562
|
+
attrs.push(`${htmlName}="${String(value)}"`);
|
|
542
563
|
}
|
|
543
564
|
}
|
|
544
565
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reverse.d.ts","sourceRoot":"","sources":["../../src/compiler/reverse.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,YAAY,CAAA;AAqlBzD,wBAAsB,cAAc,CAClC,UAAU,EAAE;IACV,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,QAAQ,EAAE,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B,cAAc,CAAC,EAAE,GAAG,EAAE,CAAA;IACtB,WAAW,CAAC,EAAE,GAAG,EAAE,CAAA;IACnB,UAAU,CAAC,EAAE,GAAG,EAAE,CAAA;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CACnB,EACD,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE;IACL,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,YAAY,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAC5E,iBAoFF;
|
|
1
|
+
{"version":3,"file":"reverse.d.ts","sourceRoot":"","sources":["../../src/compiler/reverse.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,YAAY,CAAA;AAqlBzD,wBAAsB,cAAc,CAClC,UAAU,EAAE;IACV,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,QAAQ,EAAE,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B,cAAc,CAAC,EAAE,GAAG,EAAE,CAAA;IACtB,WAAW,CAAC,EAAE,GAAG,EAAE,CAAA;IACnB,UAAU,CAAC,EAAE,GAAG,EAAE,CAAA;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CACnB,EACD,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE;IACL,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,YAAY,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAC5E,iBAoFF;AAgiDD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKpD"}
|
package/dist/compiler/reverse.js
CHANGED
|
@@ -770,6 +770,11 @@ function generateCustomValidationFunctions(node) {
|
|
|
770
770
|
}
|
|
771
771
|
function collect(n) {
|
|
772
772
|
if (n.component.type === 'InputBox') {
|
|
773
|
+
if (n.component.validation_formula !== 'custom') {
|
|
774
|
+
for (const child of n.children)
|
|
775
|
+
collect(child);
|
|
776
|
+
return;
|
|
777
|
+
}
|
|
773
778
|
const value = n.component.custom_validation_function;
|
|
774
779
|
if (typeof value !== 'string' || !value)
|
|
775
780
|
return;
|
|
@@ -968,8 +973,10 @@ function generateJSX(node, indent = 4, pageKey, componentId, nameMap, validation
|
|
|
968
973
|
if (value === null || value === undefined)
|
|
969
974
|
continue;
|
|
970
975
|
if (typeof value === 'string') {
|
|
971
|
-
// custom_validation_function: emit
|
|
976
|
+
// custom_validation_function: only emit when validation_formula is "custom"; otherwise ignore (removed on save).
|
|
972
977
|
if (key === 'custom_validation_function') {
|
|
978
|
+
if (comp.validation_formula !== 'custom')
|
|
979
|
+
continue;
|
|
973
980
|
const fnName = validationFunctionNameMap?.get(comp.id) ?? identifierToGeneratedName?.get(value) ?? value;
|
|
974
981
|
props.push(`custom_validation_function={${fnName}}`);
|
|
975
982
|
continue;
|
|
@@ -1210,13 +1217,15 @@ function htmlToJSXChildren(html, indent) {
|
|
|
1210
1217
|
if (!attrMatch[0].includes('=')) {
|
|
1211
1218
|
continue;
|
|
1212
1219
|
}
|
|
1213
|
-
// Convert HTML attribute names to JSX (e.g., class -> className, for -> htmlFor)
|
|
1220
|
+
// Convert HTML attribute names to JSX (e.g., class -> className, for -> htmlFor).
|
|
1221
|
+
// Normalize classname (wrong serialization) to className so round-trip fixes bad HTML.
|
|
1214
1222
|
let jsxAttrName = attrName;
|
|
1215
|
-
|
|
1223
|
+
const attrLower = attrName.toLowerCase();
|
|
1224
|
+
if (attrLower === 'class' || attrLower === 'classname')
|
|
1216
1225
|
jsxAttrName = 'className';
|
|
1217
|
-
else if (
|
|
1226
|
+
else if (attrLower === 'for')
|
|
1218
1227
|
jsxAttrName = 'htmlFor';
|
|
1219
|
-
else if (
|
|
1228
|
+
else if (attrLower === 'tabindex')
|
|
1220
1229
|
jsxAttrName = 'tabIndex';
|
|
1221
1230
|
// Handle style attribute: convert CSS string to JSX object
|
|
1222
1231
|
if (attrName === 'style' && attrValue) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=TEMP%20helpers%20file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TEMP helpers file.d.ts","sourceRoot":"","sources":["../../src/helpers/TEMP helpers file.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type Component, type GlobalComponentLocation, type InsertPosition, SetMultipleEmbeddableUpdateCommands } from '../types-builder';
|
|
2
|
+
export declare function translateJsonDiffToEditCommands({ previousObject, currentObject, path, objectMatchKeys, basePath, forceObjectKeyInFirstLevelIteration, extraAlternativePathObjectMatchKeys, }: {
|
|
3
|
+
previousObject: any;
|
|
4
|
+
currentObject: any;
|
|
5
|
+
path?: string[];
|
|
6
|
+
objectMatchKeys?: {
|
|
7
|
+
[k: string]: string;
|
|
8
|
+
};
|
|
9
|
+
basePath?: string[];
|
|
10
|
+
forceObjectKeyInFirstLevelIteration?: string;
|
|
11
|
+
extraAlternativePathObjectMatchKeys?: string[];
|
|
12
|
+
}): SetMultipleEmbeddableUpdateCommands;
|
|
13
|
+
export declare function translateArrayJsonDiffToEditCommands({ previousArray, currentArray, path, objectMatchKeys, basePath, extraAlternativePathObjectMatchKeys, }: {
|
|
14
|
+
previousArray: any[];
|
|
15
|
+
currentArray: any[];
|
|
16
|
+
path?: string[];
|
|
17
|
+
objectMatchKeys?: {
|
|
18
|
+
[k: string]: string;
|
|
19
|
+
};
|
|
20
|
+
basePath?: string[];
|
|
21
|
+
extraAlternativePathObjectMatchKeys?: string[];
|
|
22
|
+
}): SetMultipleEmbeddableUpdateCommands;
|
|
23
|
+
export declare function findAncestorsOfComponent({ components, componentId, }: {
|
|
24
|
+
components: Component[];
|
|
25
|
+
componentId: string;
|
|
26
|
+
}): Component[];
|
|
27
|
+
export declare function getInsertPositionForComponent({ afterComponentId, beforeComponentId, parentComponentId, globalLocation, components, isGlobalComponents, }: {
|
|
28
|
+
afterComponentId?: string;
|
|
29
|
+
beforeComponentId?: string;
|
|
30
|
+
parentComponentId?: string;
|
|
31
|
+
globalLocation?: GlobalComponentLocation;
|
|
32
|
+
components: Component[];
|
|
33
|
+
isGlobalComponents?: boolean;
|
|
34
|
+
}): InsertPosition | undefined;
|
|
35
|
+
export declare function deepEqual(obj1: any, obj2: any): boolean;
|
|
36
|
+
export declare function findUniqueKey(arr: {
|
|
37
|
+
[key: string]: any;
|
|
38
|
+
}[]): string[];
|
|
39
|
+
export declare function findDifferentPaths(obj1: any, obj2: any): Record<string, string[]>;
|
|
40
|
+
export declare function getValueByPath(obj: any, path: string[]): any;
|
|
41
|
+
export declare function getBreakLineStringFromArray(input: any): any;
|
|
42
|
+
export declare function getMultilanguageKey({ attributeKey, languageKey, }: {
|
|
43
|
+
attributeKey: string;
|
|
44
|
+
languageKey: string;
|
|
45
|
+
}): string;
|
|
46
|
+
export declare function getArrayFromBreakLineString(input: string): string[];
|
|
47
|
+
//# sourceMappingURL=json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/helpers/json.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,SAAS,EACd,KAAK,uBAAuB,EAC5B,KAAK,cAAc,EACnB,mCAAmC,EACpC,MAAM,kBAAkB,CAAA;AAEzB,wBAAgB,+BAA+B,CAAC,EAC9C,cAAmB,EACnB,aAAkB,EAClB,IAAS,EACT,eAAoB,EACpB,QAAa,EACb,mCAAmC,EACnC,mCAAwC,GACzC,EAAE;IACD,cAAc,EAAE,GAAG,CAAA;IACnB,aAAa,EAAE,GAAG,CAAA;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,eAAe,CAAC,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IACzC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,mCAAmC,CAAC,EAAE,MAAM,CAAA;IAC5C,mCAAmC,CAAC,EAAE,MAAM,EAAE,CAAA;CAC/C,GAAG,mCAAmC,CA6JtC;AAED,wBAAgB,oCAAoC,CAAC,EACnD,aAAkB,EAClB,YAAiB,EACjB,IAAS,EACT,eAAoB,EACpB,QAAa,EACb,mCAAwC,GACzC,EAAE;IACD,aAAa,EAAE,GAAG,EAAE,CAAA;IACpB,YAAY,EAAE,GAAG,EAAE,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,eAAe,CAAC,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IACzC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,mCAAmC,CAAC,EAAE,MAAM,EAAE,CAAA;CAC/C,GAAG,mCAAmC,CA2MtC;AAGD,wBAAgB,wBAAwB,CAAC,EACvC,UAAU,EACV,WAAW,GACZ,EAAE;IACD,UAAU,EAAE,SAAS,EAAE,CAAA;IACvB,WAAW,EAAE,MAAM,CAAA;CACpB,GAAG,SAAS,EAAE,CAsBd;AAsDD,wBAAgB,6BAA6B,CAAC,EAC5C,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,UAAU,EACV,kBAAkB,GACnB,EAAE;IACD,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,cAAc,CAAC,EAAE,uBAAuB,CAAA;IACxC,UAAU,EAAE,SAAS,EAAE,CAAA;IACvB,kBAAkB,CAAC,EAAE,OAAO,CAAA;CAC7B,GAAG,cAAc,GAAG,SAAS,CAgI7B;AAKD,wBAAgB,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,WAkB7C;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CAAE,EAAE,GAAG,MAAM,EAAE,CA6BrE;AAGD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAqEjF;AAGD,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,OAYtD;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,GAAG,OAGrD;AAMD,wBAAgB,mBAAmB,CAAC,EAClC,YAAY,EACZ,WAAW,GACZ,EAAE;IACD,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;CACpB,GAAG,MAAM,CAIT;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,YAGxD"}
|