@tailor-platform/sdk 1.12.0 → 1.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/cli/index.mjs +6 -4
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lib.d.mts +119 -4
- package/dist/cli/lib.mjs +1 -1
- package/dist/configure/index.d.mts +2 -2
- package/dist/{index-Bid18Opo.d.mts → index-Bw_huFr7.d.mts} +7 -7
- package/dist/{index-BBr_q3vB.d.mts → index-DMoFYBhB.d.mts} +2 -2
- package/dist/{update-B_W-UQnS.mjs → update-BnKKm4aR.mjs} +504 -120
- package/dist/update-BnKKm4aR.mjs.map +1 -0
- package/dist/utils/test/index.d.mts +2 -2
- package/docs/cli/application.md +38 -38
- package/docs/cli/auth.md +24 -24
- package/docs/cli/completion.md +27 -0
- package/docs/cli/executor.md +36 -36
- package/docs/cli/secret.md +41 -41
- package/docs/cli/staticwebsite.md +17 -17
- package/docs/cli/tailordb.md +48 -48
- package/docs/cli/user.md +17 -17
- package/docs/cli/workflow.md +39 -39
- package/docs/cli/workspace.md +76 -76
- package/docs/cli-reference.md +8 -0
- package/docs/generator/builtin.md +24 -19
- package/package.json +2 -2
- package/dist/update-B_W-UQnS.mjs.map +0 -1
|
@@ -3749,13 +3749,19 @@ function generateIdpUserSeedCall(hasIdpUser) {
|
|
|
3749
3749
|
/**
|
|
3750
3750
|
* Generates the exec.mjs script content using testExecScript API for TailorDB types
|
|
3751
3751
|
* and GraphQL mutation for _User (IdP managed)
|
|
3752
|
-
* @param
|
|
3752
|
+
* @param defaultMachineUserName - Default machine user name from generator config (can be overridden at runtime)
|
|
3753
3753
|
* @param relativeConfigPath - Config path relative to exec script
|
|
3754
3754
|
* @param namespaceConfigs - Namespace configurations with types and dependencies
|
|
3755
3755
|
* @param hasIdpUser - Whether _User is included
|
|
3756
3756
|
* @returns exec.mjs file contents
|
|
3757
3757
|
*/
|
|
3758
|
-
function generateExecScript(
|
|
3758
|
+
function generateExecScript(defaultMachineUserName, relativeConfigPath, namespaceConfigs, hasIdpUser) {
|
|
3759
|
+
const namespaceEntitiesEntries = namespaceConfigs.map(({ namespace, types }) => {
|
|
3760
|
+
return ` "${namespace}": [\n${types.map((e) => ` "${e}",`).join("\n")}\n ]`;
|
|
3761
|
+
}).join(",\n");
|
|
3762
|
+
const namespaceDepsEntries = namespaceConfigs.map(({ namespace, dependencies }) => {
|
|
3763
|
+
return ` "${namespace}": {\n${Object.entries(dependencies).map(([type, deps]) => ` "${type}": [${deps.map((d) => `"${d}"`).join(", ")}]`).join(",\n")}\n }`;
|
|
3764
|
+
}).join(",\n");
|
|
3759
3765
|
return ml`
|
|
3760
3766
|
import { readFileSync } from "node:fs";
|
|
3761
3767
|
import { join } from "node:path";
|
|
@@ -3776,6 +3782,7 @@ function generateExecScript(machineUserName, relativeConfigPath, namespaceConfig
|
|
|
3776
3782
|
// Parse command-line arguments
|
|
3777
3783
|
const { values, positionals } = parseArgs({
|
|
3778
3784
|
options: {
|
|
3785
|
+
"machine-user": { type: "string", short: "m" },
|
|
3779
3786
|
namespace: { type: "string", short: "n" },
|
|
3780
3787
|
"skip-idp": { type: "boolean", default: false },
|
|
3781
3788
|
truncate: { type: "boolean", default: false },
|
|
@@ -3791,15 +3798,16 @@ function generateExecScript(machineUserName, relativeConfigPath, namespaceConfig
|
|
|
3791
3798
|
Usage: node exec.mjs [options] [types...]
|
|
3792
3799
|
|
|
3793
3800
|
Options:
|
|
3794
|
-
-
|
|
3795
|
-
|
|
3796
|
-
--
|
|
3797
|
-
--
|
|
3798
|
-
|
|
3799
|
-
-
|
|
3801
|
+
-m, --machine-user <name> Machine user name for authentication (required if not configured)
|
|
3802
|
+
-n, --namespace <ns> Process all types in specified namespace (excludes _User)
|
|
3803
|
+
--skip-idp Skip IdP user (_User) entity
|
|
3804
|
+
--truncate Truncate tables before seeding
|
|
3805
|
+
--yes Skip confirmation prompts (for truncate)
|
|
3806
|
+
-p, --profile <name> Workspace profile name
|
|
3807
|
+
-h, --help Show help
|
|
3800
3808
|
|
|
3801
3809
|
Examples:
|
|
3802
|
-
node exec.mjs
|
|
3810
|
+
node exec.mjs -m admin # Process all types with machine user
|
|
3803
3811
|
node exec.mjs --namespace <namespace> # Process tailordb namespace only (no _User)
|
|
3804
3812
|
node exec.mjs User Order # Process specific types only
|
|
3805
3813
|
node exec.mjs --skip-idp # Process all except _User
|
|
@@ -3829,16 +3837,22 @@ function generateExecScript(machineUserName, relativeConfigPath, namespaceConfig
|
|
|
3829
3837
|
const configDir = import.meta.dirname;
|
|
3830
3838
|
const configPath = join(configDir, "${relativeConfigPath}");
|
|
3831
3839
|
|
|
3840
|
+
// Determine machine user name (CLI argument takes precedence over config default)
|
|
3841
|
+
const defaultMachineUser = ${defaultMachineUserName ? `"${defaultMachineUserName}"` : "undefined"};
|
|
3842
|
+
const machineUserName = values["machine-user"] || defaultMachineUser;
|
|
3843
|
+
|
|
3844
|
+
if (!machineUserName) {
|
|
3845
|
+
console.error(styleText("red", "Error: Machine user name is required."));
|
|
3846
|
+
console.error(styleText("yellow", "Specify --machine-user <name> or configure machineUserName in generator options."));
|
|
3847
|
+
process.exit(1);
|
|
3848
|
+
}
|
|
3849
|
+
|
|
3832
3850
|
// Entity configuration
|
|
3833
3851
|
const namespaceEntities = {
|
|
3834
|
-
${
|
|
3835
|
-
return ` "${namespace}": [\n${types.map((e) => ` "${e}",`).join("\n")}\n ]`;
|
|
3836
|
-
}).join(",\n")}
|
|
3852
|
+
${namespaceEntitiesEntries}
|
|
3837
3853
|
};
|
|
3838
3854
|
const namespaceDeps = {
|
|
3839
|
-
${
|
|
3840
|
-
return ` "${namespace}": {\n${Object.entries(dependencies).map(([type, deps]) => ` "${type}": [${deps.map((d) => `"${d}"`).join(", ")}]`).join(",\n")}\n }`;
|
|
3841
|
-
}).join(",\n")}
|
|
3855
|
+
${namespaceDepsEntries}
|
|
3842
3856
|
};
|
|
3843
3857
|
const entities = Object.values(namespaceEntities).flat();
|
|
3844
3858
|
const hasIdpUser = ${String(hasIdpUser)};
|
|
@@ -3963,7 +3977,7 @@ ${namespaceConfigs.map(({ namespace, dependencies }) => {
|
|
|
3963
3977
|
|
|
3964
3978
|
// Get machine user token
|
|
3965
3979
|
const tokenInfo = await getMachineUserToken({
|
|
3966
|
-
name:
|
|
3980
|
+
name: machineUserName,
|
|
3967
3981
|
configPath,
|
|
3968
3982
|
profile: values.profile,
|
|
3969
3983
|
});
|
|
@@ -4071,7 +4085,7 @@ ${namespaceConfigs.map(({ namespace, dependencies }) => {
|
|
|
4071
4085
|
arg: JSON.stringify({ data: chunk.data, order: chunk.order }),
|
|
4072
4086
|
invoker: {
|
|
4073
4087
|
namespace: authNamespace,
|
|
4074
|
-
machineUserName
|
|
4088
|
+
machineUserName,
|
|
4075
4089
|
},
|
|
4076
4090
|
});
|
|
4077
4091
|
|
|
@@ -4251,13 +4265,11 @@ function createSeedGenerator(options) {
|
|
|
4251
4265
|
content: generateIdpUserSchemaFile(idpUser.schema.usernameField, idpUser.schema.userTypeName)
|
|
4252
4266
|
});
|
|
4253
4267
|
}
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
});
|
|
4260
|
-
}
|
|
4268
|
+
const relativeConfigPath = path.relative(options.distPath, configPath);
|
|
4269
|
+
files.push({
|
|
4270
|
+
path: path.join(options.distPath, "exec.mjs"),
|
|
4271
|
+
content: generateExecScript(options.machineUserName, relativeConfigPath, namespaceConfigs, hasIdpUser)
|
|
4272
|
+
});
|
|
4261
4273
|
return { files };
|
|
4262
4274
|
}
|
|
4263
4275
|
};
|
|
@@ -7595,6 +7607,16 @@ function formatDiffChange(change) {
|
|
|
7595
7607
|
const after = change.after;
|
|
7596
7608
|
return ` ~ ${change.fieldName}: ${formatFieldModification(before, after)}`;
|
|
7597
7609
|
}
|
|
7610
|
+
case "index_added": return ` + [Index] ${change.indexName}`;
|
|
7611
|
+
case "index_removed": return ` - [Index] ${change.indexName}`;
|
|
7612
|
+
case "index_modified": return ` ~ [Index] ${change.indexName}: ${change.reason ?? "modified"}`;
|
|
7613
|
+
case "file_added": return ` + [File] ${change.fieldName}`;
|
|
7614
|
+
case "file_removed": return ` - [File] ${change.fieldName}`;
|
|
7615
|
+
case "file_modified": return ` ~ [File] ${change.fieldName}: ${change.reason ?? "modified"}`;
|
|
7616
|
+
case "relationship_added": return ` + [Relationship${change.relationshipType ? ` (${change.relationshipType})` : ""}] ${change.relationshipName}`;
|
|
7617
|
+
case "relationship_removed": return ` - [Relationship${change.relationshipType ? ` (${change.relationshipType})` : ""}] ${change.relationshipName}`;
|
|
7618
|
+
case "relationship_modified": return ` ~ [Relationship${change.relationshipType ? ` (${change.relationshipType})` : ""}] ${change.relationshipName}: ${change.reason ?? "modified"}`;
|
|
7619
|
+
case "permission_modified": return ` ~ [Permission] ${change.reason ?? "modified"}`;
|
|
7598
7620
|
default: return ` ? ${change.typeName}.${change.fieldName ?? ""}`;
|
|
7599
7621
|
}
|
|
7600
7622
|
}
|
|
@@ -7623,10 +7645,22 @@ function formatFieldModification(before, after) {
|
|
|
7623
7645
|
if (Boolean(before.array) !== Boolean(after.array)) changes.push(`array: ${before.array ?? false} → ${after.array ?? false}`);
|
|
7624
7646
|
if (Boolean(before.index) !== Boolean(after.index)) changes.push(`index: ${before.index ?? false} → ${after.index ?? false}`);
|
|
7625
7647
|
if (Boolean(before.unique) !== Boolean(after.unique)) changes.push(`unique: ${before.unique ?? false} → ${after.unique ?? false}`);
|
|
7648
|
+
if (Boolean(before.vector) !== Boolean(after.vector)) changes.push(`vector: ${before.vector ?? false} → ${after.vector ?? false}`);
|
|
7626
7649
|
const beforeAllowed = before.allowedValues ?? [];
|
|
7627
7650
|
const afterAllowed = after.allowedValues ?? [];
|
|
7628
|
-
const afterSet = new Set(afterAllowed);
|
|
7629
|
-
if (beforeAllowed.length !== afterAllowed.length || beforeAllowed.some((v) => !afterSet.has(v)))
|
|
7651
|
+
const afterSet = new Set(afterAllowed.map((v) => v.value));
|
|
7652
|
+
if (beforeAllowed.length !== afterAllowed.length || beforeAllowed.some((v) => !afterSet.has(v.value))) {
|
|
7653
|
+
const beforeValues = beforeAllowed.map((v) => v.value).join(", ");
|
|
7654
|
+
const afterValues = afterAllowed.map((v) => v.value).join(", ");
|
|
7655
|
+
changes.push(`allowedValues: [${beforeValues}] → [${afterValues}]`);
|
|
7656
|
+
}
|
|
7657
|
+
const beforeHooks = before.hooks;
|
|
7658
|
+
const afterHooks = after.hooks;
|
|
7659
|
+
if ((beforeHooks?.create?.expr ?? "") !== (afterHooks?.create?.expr ?? "") || (beforeHooks?.update?.expr ?? "") !== (afterHooks?.update?.expr ?? "")) changes.push("hooks modified");
|
|
7660
|
+
const beforeValidate = before.validate ?? [];
|
|
7661
|
+
const afterValidate = after.validate ?? [];
|
|
7662
|
+
if (beforeValidate.length !== afterValidate.length) changes.push(`validations: ${beforeValidate.length} → ${afterValidate.length}`);
|
|
7663
|
+
if (Boolean(before.serial) !== Boolean(after.serial)) changes.push(`serial: ${before.serial ? "enabled" : "disabled"} → ${after.serial ? "enabled" : "disabled"}`);
|
|
7630
7664
|
return changes.join(", ");
|
|
7631
7665
|
}
|
|
7632
7666
|
/**
|
|
@@ -7643,44 +7677,34 @@ function formatBreakingChanges(breakingChanges) {
|
|
|
7643
7677
|
}
|
|
7644
7678
|
return lines.join("\n");
|
|
7645
7679
|
}
|
|
7680
|
+
const DIFF_CHANGE_LABELS = {
|
|
7681
|
+
type_added: "type(s) added",
|
|
7682
|
+
type_removed: "type(s) removed",
|
|
7683
|
+
type_modified: "type(s) modified",
|
|
7684
|
+
field_added: "field(s) added",
|
|
7685
|
+
field_removed: "field(s) removed",
|
|
7686
|
+
field_modified: "field(s) modified",
|
|
7687
|
+
index_added: "index(es) added",
|
|
7688
|
+
index_removed: "index(es) removed",
|
|
7689
|
+
index_modified: "index(es) modified",
|
|
7690
|
+
file_added: "file field(s) added",
|
|
7691
|
+
file_removed: "file field(s) removed",
|
|
7692
|
+
file_modified: "file field(s) modified",
|
|
7693
|
+
relationship_added: "relationship(s) added",
|
|
7694
|
+
relationship_removed: "relationship(s) removed",
|
|
7695
|
+
relationship_modified: "relationship(s) modified",
|
|
7696
|
+
permission_modified: "permission(s) modified"
|
|
7697
|
+
};
|
|
7646
7698
|
/**
|
|
7647
7699
|
* Format a summary of the migration diff
|
|
7648
7700
|
* @param {MigrationDiff} diff - Migration diff to summarize
|
|
7649
7701
|
* @returns {string} Formatted summary string
|
|
7650
7702
|
*/
|
|
7651
7703
|
function formatDiffSummary(diff) {
|
|
7652
|
-
const stats = {
|
|
7653
|
-
|
|
7654
|
-
|
|
7655
|
-
|
|
7656
|
-
fieldsRemoved: 0,
|
|
7657
|
-
fieldsModified: 0
|
|
7658
|
-
};
|
|
7659
|
-
for (const change of diff.changes) switch (change.kind) {
|
|
7660
|
-
case "type_added":
|
|
7661
|
-
stats.typesAdded++;
|
|
7662
|
-
break;
|
|
7663
|
-
case "type_removed":
|
|
7664
|
-
stats.typesRemoved++;
|
|
7665
|
-
break;
|
|
7666
|
-
case "field_added":
|
|
7667
|
-
stats.fieldsAdded++;
|
|
7668
|
-
break;
|
|
7669
|
-
case "field_removed":
|
|
7670
|
-
stats.fieldsRemoved++;
|
|
7671
|
-
break;
|
|
7672
|
-
case "field_modified":
|
|
7673
|
-
stats.fieldsModified++;
|
|
7674
|
-
break;
|
|
7675
|
-
}
|
|
7676
|
-
const parts = [];
|
|
7677
|
-
if (stats.typesAdded > 0) parts.push(`${stats.typesAdded} type(s) added`);
|
|
7678
|
-
if (stats.typesRemoved > 0) parts.push(`${stats.typesRemoved} type(s) removed`);
|
|
7679
|
-
if (stats.fieldsAdded > 0) parts.push(`${stats.fieldsAdded} field(s) added`);
|
|
7680
|
-
if (stats.fieldsRemoved > 0) parts.push(`${stats.fieldsRemoved} field(s) removed`);
|
|
7681
|
-
if (stats.fieldsModified > 0) parts.push(`${stats.fieldsModified} field(s) modified`);
|
|
7682
|
-
if (parts.length === 0) return "No changes";
|
|
7683
|
-
return parts.join(", ");
|
|
7704
|
+
const stats = {};
|
|
7705
|
+
for (const change of diff.changes) stats[change.kind] = (stats[change.kind] ?? 0) + 1;
|
|
7706
|
+
const parts = Object.keys(stats).map((kind) => `${stats[kind]} ${DIFF_CHANGE_LABELS[kind]}`);
|
|
7707
|
+
return parts.length > 0 ? parts.join(", ") : "No changes";
|
|
7684
7708
|
}
|
|
7685
7709
|
|
|
7686
7710
|
//#endregion
|
|
@@ -7763,12 +7787,79 @@ function createSnapshotFieldConfig(field) {
|
|
|
7763
7787
|
if (field.config.array) config.array = true;
|
|
7764
7788
|
if (field.config.index) config.index = true;
|
|
7765
7789
|
if (field.config.unique) config.unique = true;
|
|
7766
|
-
if (field.config.allowedValues && field.config.allowedValues.length > 0) config.allowedValues = field.config.allowedValues.map((v) =>
|
|
7790
|
+
if (field.config.allowedValues && field.config.allowedValues.length > 0) config.allowedValues = field.config.allowedValues.map((v) => ({
|
|
7791
|
+
value: v.value,
|
|
7792
|
+
...v.description && { description: v.description }
|
|
7793
|
+
}));
|
|
7767
7794
|
if (field.config.foreignKey) {
|
|
7768
7795
|
config.foreignKey = true;
|
|
7769
7796
|
if (field.config.foreignKeyType) config.foreignKeyType = field.config.foreignKeyType;
|
|
7770
7797
|
if (field.config.foreignKeyField) config.foreignKeyField = field.config.foreignKeyField;
|
|
7771
7798
|
}
|
|
7799
|
+
if (field.config.description) config.description = field.config.description;
|
|
7800
|
+
if (field.config.vector) config.vector = true;
|
|
7801
|
+
if (field.config.hooks) {
|
|
7802
|
+
config.hooks = {};
|
|
7803
|
+
if (field.config.hooks.create) config.hooks.create = { expr: field.config.hooks.create.expr };
|
|
7804
|
+
if (field.config.hooks.update) config.hooks.update = { expr: field.config.hooks.update.expr };
|
|
7805
|
+
}
|
|
7806
|
+
if (field.config.validate && field.config.validate.length > 0) config.validate = field.config.validate.map((v) => ({
|
|
7807
|
+
script: { expr: v.script.expr },
|
|
7808
|
+
errorMessage: v.errorMessage
|
|
7809
|
+
}));
|
|
7810
|
+
if (field.config.serial) config.serial = {
|
|
7811
|
+
start: field.config.serial.start,
|
|
7812
|
+
...field.config.serial.maxValue !== void 0 && { maxValue: field.config.serial.maxValue },
|
|
7813
|
+
...field.config.serial.format && { format: field.config.serial.format }
|
|
7814
|
+
};
|
|
7815
|
+
if (field.config.fields && Object.keys(field.config.fields).length > 0) {
|
|
7816
|
+
config.fields = {};
|
|
7817
|
+
for (const [nestedName, nestedConfig] of Object.entries(field.config.fields)) config.fields[nestedName] = createSnapshotFieldConfigFromOperatorConfig(nestedConfig);
|
|
7818
|
+
}
|
|
7819
|
+
return config;
|
|
7820
|
+
}
|
|
7821
|
+
/**
|
|
7822
|
+
* Create a snapshot field config from an OperatorFieldConfig (for nested fields)
|
|
7823
|
+
* @param {import("@/parser/service/tailordb/types").OperatorFieldConfig} fieldConfig - Field configuration
|
|
7824
|
+
* @returns {SnapshotFieldConfig} Snapshot field configuration
|
|
7825
|
+
*/
|
|
7826
|
+
function createSnapshotFieldConfigFromOperatorConfig(fieldConfig) {
|
|
7827
|
+
const config = {
|
|
7828
|
+
type: fieldConfig.type,
|
|
7829
|
+
required: fieldConfig.required !== false
|
|
7830
|
+
};
|
|
7831
|
+
if (fieldConfig.array) config.array = true;
|
|
7832
|
+
if (fieldConfig.index) config.index = true;
|
|
7833
|
+
if (fieldConfig.unique) config.unique = true;
|
|
7834
|
+
if (fieldConfig.allowedValues && fieldConfig.allowedValues.length > 0) config.allowedValues = fieldConfig.allowedValues.map((v) => ({
|
|
7835
|
+
value: v.value,
|
|
7836
|
+
...v.description && { description: v.description }
|
|
7837
|
+
}));
|
|
7838
|
+
if (fieldConfig.foreignKey) {
|
|
7839
|
+
config.foreignKey = true;
|
|
7840
|
+
if (fieldConfig.foreignKeyType) config.foreignKeyType = fieldConfig.foreignKeyType;
|
|
7841
|
+
if (fieldConfig.foreignKeyField) config.foreignKeyField = fieldConfig.foreignKeyField;
|
|
7842
|
+
}
|
|
7843
|
+
if (fieldConfig.description) config.description = fieldConfig.description;
|
|
7844
|
+
if (fieldConfig.vector) config.vector = true;
|
|
7845
|
+
if (fieldConfig.hooks) {
|
|
7846
|
+
config.hooks = {};
|
|
7847
|
+
if (fieldConfig.hooks.create) config.hooks.create = { expr: fieldConfig.hooks.create.expr };
|
|
7848
|
+
if (fieldConfig.hooks.update) config.hooks.update = { expr: fieldConfig.hooks.update.expr };
|
|
7849
|
+
}
|
|
7850
|
+
if (fieldConfig.validate && fieldConfig.validate.length > 0) config.validate = fieldConfig.validate.map((v) => ({
|
|
7851
|
+
script: { expr: v.script.expr },
|
|
7852
|
+
errorMessage: v.errorMessage
|
|
7853
|
+
}));
|
|
7854
|
+
if (fieldConfig.serial) config.serial = {
|
|
7855
|
+
start: fieldConfig.serial.start,
|
|
7856
|
+
...fieldConfig.serial.maxValue !== void 0 && { maxValue: fieldConfig.serial.maxValue },
|
|
7857
|
+
...fieldConfig.serial.format && { format: fieldConfig.serial.format }
|
|
7858
|
+
};
|
|
7859
|
+
if (fieldConfig.fields && Object.keys(fieldConfig.fields).length > 0) {
|
|
7860
|
+
config.fields = {};
|
|
7861
|
+
for (const [nestedName, nestedConfig] of Object.entries(fieldConfig.fields)) config.fields[nestedName] = createSnapshotFieldConfigFromOperatorConfig(nestedConfig);
|
|
7862
|
+
}
|
|
7772
7863
|
return config;
|
|
7773
7864
|
}
|
|
7774
7865
|
/**
|
|
@@ -7807,9 +7898,56 @@ function createSnapshotType(type) {
|
|
|
7807
7898
|
};
|
|
7808
7899
|
}
|
|
7809
7900
|
if (type.files && Object.keys(type.files).length > 0) snapshotType.files = { ...type.files };
|
|
7901
|
+
if (Object.keys(type.forwardRelationships).length > 0) {
|
|
7902
|
+
snapshotType.forwardRelationships = {};
|
|
7903
|
+
for (const [relName, rel] of Object.entries(type.forwardRelationships)) snapshotType.forwardRelationships[relName] = {
|
|
7904
|
+
targetType: rel.targetType,
|
|
7905
|
+
targetField: rel.targetField,
|
|
7906
|
+
sourceField: rel.sourceField,
|
|
7907
|
+
isArray: rel.isArray,
|
|
7908
|
+
description: rel.description
|
|
7909
|
+
};
|
|
7910
|
+
}
|
|
7911
|
+
if (Object.keys(type.backwardRelationships).length > 0) {
|
|
7912
|
+
snapshotType.backwardRelationships = {};
|
|
7913
|
+
for (const [relName, rel] of Object.entries(type.backwardRelationships)) snapshotType.backwardRelationships[relName] = {
|
|
7914
|
+
targetType: rel.targetType,
|
|
7915
|
+
targetField: rel.targetField,
|
|
7916
|
+
sourceField: rel.sourceField,
|
|
7917
|
+
isArray: rel.isArray,
|
|
7918
|
+
description: rel.description
|
|
7919
|
+
};
|
|
7920
|
+
}
|
|
7921
|
+
if (type.permissions.record || type.permissions.gql) {
|
|
7922
|
+
snapshotType.permissions = {};
|
|
7923
|
+
if (type.permissions.record) snapshotType.permissions.record = {
|
|
7924
|
+
create: type.permissions.record.create.map(convertActionPermission),
|
|
7925
|
+
read: type.permissions.record.read.map(convertActionPermission),
|
|
7926
|
+
update: type.permissions.record.update.map(convertActionPermission),
|
|
7927
|
+
delete: type.permissions.record.delete.map(convertActionPermission)
|
|
7928
|
+
};
|
|
7929
|
+
if (type.permissions.gql) snapshotType.permissions.gql = type.permissions.gql.map((policy) => ({
|
|
7930
|
+
conditions: policy.conditions,
|
|
7931
|
+
actions: policy.actions,
|
|
7932
|
+
permit: policy.permit,
|
|
7933
|
+
...policy.description && { description: policy.description }
|
|
7934
|
+
}));
|
|
7935
|
+
}
|
|
7810
7936
|
return snapshotType;
|
|
7811
7937
|
}
|
|
7812
7938
|
/**
|
|
7939
|
+
* Convert an action permission to snapshot format
|
|
7940
|
+
* @param {StandardActionPermission<"record">} permission - Action permission
|
|
7941
|
+
* @returns {SnapshotActionPermission} Snapshot action permission
|
|
7942
|
+
*/
|
|
7943
|
+
function convertActionPermission(permission) {
|
|
7944
|
+
return {
|
|
7945
|
+
conditions: permission.conditions,
|
|
7946
|
+
permit: permission.permit,
|
|
7947
|
+
...permission.description && { description: permission.description }
|
|
7948
|
+
};
|
|
7949
|
+
}
|
|
7950
|
+
/**
|
|
7813
7951
|
* Create a schema snapshot from local type definitions
|
|
7814
7952
|
* @param {Record<string, TailorDBType>} types - Local type definitions
|
|
7815
7953
|
* @param {string} namespace - Namespace for the snapshot
|
|
@@ -7928,6 +8066,95 @@ function applyDiffToSnapshot(snapshot, diff) {
|
|
|
7928
8066
|
};
|
|
7929
8067
|
}
|
|
7930
8068
|
break;
|
|
8069
|
+
case "index_added":
|
|
8070
|
+
case "index_modified":
|
|
8071
|
+
if (types[change.typeName] && change.indexName) types[change.typeName] = {
|
|
8072
|
+
...types[change.typeName],
|
|
8073
|
+
indexes: {
|
|
8074
|
+
...types[change.typeName].indexes,
|
|
8075
|
+
[change.indexName]: change.after
|
|
8076
|
+
}
|
|
8077
|
+
};
|
|
8078
|
+
break;
|
|
8079
|
+
case "index_removed":
|
|
8080
|
+
if (types[change.typeName] && change.indexName && types[change.typeName].indexes) {
|
|
8081
|
+
const { [change.indexName]: _, ...remainingIndexes } = types[change.typeName].indexes;
|
|
8082
|
+
types[change.typeName] = {
|
|
8083
|
+
...types[change.typeName],
|
|
8084
|
+
indexes: Object.keys(remainingIndexes).length > 0 ? remainingIndexes : void 0
|
|
8085
|
+
};
|
|
8086
|
+
}
|
|
8087
|
+
break;
|
|
8088
|
+
case "file_added":
|
|
8089
|
+
case "file_modified":
|
|
8090
|
+
if (types[change.typeName] && change.fieldName) types[change.typeName] = {
|
|
8091
|
+
...types[change.typeName],
|
|
8092
|
+
files: {
|
|
8093
|
+
...types[change.typeName].files,
|
|
8094
|
+
[change.fieldName]: change.after
|
|
8095
|
+
}
|
|
8096
|
+
};
|
|
8097
|
+
break;
|
|
8098
|
+
case "file_removed":
|
|
8099
|
+
if (types[change.typeName] && change.fieldName && types[change.typeName].files) {
|
|
8100
|
+
const { [change.fieldName]: _, ...remainingFiles } = types[change.typeName].files;
|
|
8101
|
+
types[change.typeName] = {
|
|
8102
|
+
...types[change.typeName],
|
|
8103
|
+
files: Object.keys(remainingFiles).length > 0 ? remainingFiles : void 0
|
|
8104
|
+
};
|
|
8105
|
+
}
|
|
8106
|
+
break;
|
|
8107
|
+
case "relationship_added":
|
|
8108
|
+
case "relationship_modified":
|
|
8109
|
+
if (types[change.typeName] && change.relationshipName) {
|
|
8110
|
+
const rel = change.after;
|
|
8111
|
+
if ((change.relationshipType ?? (types[change.typeName].forwardRelationships?.[change.relationshipName] ? "forward" : types[change.typeName].backwardRelationships?.[change.relationshipName] ? "backward" : "forward")) === "forward") types[change.typeName] = {
|
|
8112
|
+
...types[change.typeName],
|
|
8113
|
+
forwardRelationships: {
|
|
8114
|
+
...types[change.typeName].forwardRelationships,
|
|
8115
|
+
[change.relationshipName]: rel
|
|
8116
|
+
}
|
|
8117
|
+
};
|
|
8118
|
+
else types[change.typeName] = {
|
|
8119
|
+
...types[change.typeName],
|
|
8120
|
+
backwardRelationships: {
|
|
8121
|
+
...types[change.typeName].backwardRelationships,
|
|
8122
|
+
[change.relationshipName]: rel
|
|
8123
|
+
}
|
|
8124
|
+
};
|
|
8125
|
+
}
|
|
8126
|
+
break;
|
|
8127
|
+
case "relationship_removed":
|
|
8128
|
+
if (types[change.typeName] && change.relationshipName) {
|
|
8129
|
+
const type = types[change.typeName];
|
|
8130
|
+
const targetType = change.relationshipType ?? (type.forwardRelationships?.[change.relationshipName] ? "forward" : type.backwardRelationships?.[change.relationshipName] ? "backward" : null);
|
|
8131
|
+
if (targetType === "forward" && type.forwardRelationships?.[change.relationshipName]) {
|
|
8132
|
+
const { [change.relationshipName]: _, ...remaining } = type.forwardRelationships;
|
|
8133
|
+
types[change.typeName] = {
|
|
8134
|
+
...type,
|
|
8135
|
+
forwardRelationships: Object.keys(remaining).length > 0 ? remaining : void 0
|
|
8136
|
+
};
|
|
8137
|
+
} else if (targetType === "backward" && type.backwardRelationships?.[change.relationshipName]) {
|
|
8138
|
+
const { [change.relationshipName]: _, ...remaining } = type.backwardRelationships;
|
|
8139
|
+
types[change.typeName] = {
|
|
8140
|
+
...type,
|
|
8141
|
+
backwardRelationships: Object.keys(remaining).length > 0 ? remaining : void 0
|
|
8142
|
+
};
|
|
8143
|
+
}
|
|
8144
|
+
}
|
|
8145
|
+
break;
|
|
8146
|
+
case "permission_modified":
|
|
8147
|
+
if (types[change.typeName] && change.after) {
|
|
8148
|
+
const after = change.after;
|
|
8149
|
+
types[change.typeName] = {
|
|
8150
|
+
...types[change.typeName],
|
|
8151
|
+
permissions: {
|
|
8152
|
+
record: after.recordPermission,
|
|
8153
|
+
gql: after.gqlPermission
|
|
8154
|
+
}
|
|
8155
|
+
};
|
|
8156
|
+
}
|
|
8157
|
+
break;
|
|
7931
8158
|
}
|
|
7932
8159
|
return {
|
|
7933
8160
|
...snapshot,
|
|
@@ -7979,15 +8206,51 @@ function areFieldsDifferent(oldField, newField) {
|
|
|
7979
8206
|
"array",
|
|
7980
8207
|
"index",
|
|
7981
8208
|
"unique",
|
|
7982
|
-
"foreignKey"
|
|
8209
|
+
"foreignKey",
|
|
8210
|
+
"vector"
|
|
7983
8211
|
]) if ((oldField[prop] ?? false) !== (newField[prop] ?? false)) return true;
|
|
7984
8212
|
if (oldField.foreignKeyType !== newField.foreignKeyType) return true;
|
|
7985
8213
|
if (oldField.foreignKeyField !== newField.foreignKeyField) return true;
|
|
8214
|
+
if ((oldField.description ?? "") !== (newField.description ?? "")) return true;
|
|
7986
8215
|
const oldAllowed = oldField.allowedValues ?? [];
|
|
7987
8216
|
const newAllowed = newField.allowedValues ?? [];
|
|
7988
8217
|
if (oldAllowed.length !== newAllowed.length) return true;
|
|
7989
|
-
const
|
|
7990
|
-
|
|
8218
|
+
const newAllowedMap = new Map(newAllowed.map((v) => [v.value, v.description]));
|
|
8219
|
+
for (const v of oldAllowed) {
|
|
8220
|
+
if (!newAllowedMap.has(v.value)) return true;
|
|
8221
|
+
if ((v.description ?? "") !== (newAllowedMap.get(v.value) ?? "")) return true;
|
|
8222
|
+
}
|
|
8223
|
+
const oldHooks = oldField.hooks;
|
|
8224
|
+
const newHooks = newField.hooks;
|
|
8225
|
+
if (Boolean(oldHooks) !== Boolean(newHooks)) return true;
|
|
8226
|
+
if (oldHooks && newHooks) {
|
|
8227
|
+
if ((oldHooks.create?.expr ?? "") !== (newHooks.create?.expr ?? "")) return true;
|
|
8228
|
+
if ((oldHooks.update?.expr ?? "") !== (newHooks.update?.expr ?? "")) return true;
|
|
8229
|
+
}
|
|
8230
|
+
const oldValidate = oldField.validate ?? [];
|
|
8231
|
+
const newValidate = newField.validate ?? [];
|
|
8232
|
+
if (oldValidate.length !== newValidate.length) return true;
|
|
8233
|
+
for (let i = 0; i < oldValidate.length; i++) {
|
|
8234
|
+
if (oldValidate[i].script.expr !== newValidate[i].script.expr) return true;
|
|
8235
|
+
if (oldValidate[i].errorMessage !== newValidate[i].errorMessage) return true;
|
|
8236
|
+
}
|
|
8237
|
+
const oldSerial = oldField.serial;
|
|
8238
|
+
const newSerial = newField.serial;
|
|
8239
|
+
if (Boolean(oldSerial) !== Boolean(newSerial)) return true;
|
|
8240
|
+
if (oldSerial && newSerial) {
|
|
8241
|
+
if (oldSerial.start !== newSerial.start) return true;
|
|
8242
|
+
if (oldSerial.maxValue !== newSerial.maxValue) return true;
|
|
8243
|
+
if ((oldSerial.format ?? "") !== (newSerial.format ?? "")) return true;
|
|
8244
|
+
}
|
|
8245
|
+
const oldFields = oldField.fields ?? {};
|
|
8246
|
+
const newFields = newField.fields ?? {};
|
|
8247
|
+
const oldFieldNames = Object.keys(oldFields);
|
|
8248
|
+
const newFieldNames = Object.keys(newFields);
|
|
8249
|
+
if (oldFieldNames.length !== newFieldNames.length) return true;
|
|
8250
|
+
for (const fieldName of oldFieldNames) {
|
|
8251
|
+
if (!newFields[fieldName]) return true;
|
|
8252
|
+
if (areFieldsDifferent(oldFields[fieldName], newFields[fieldName])) return true;
|
|
8253
|
+
}
|
|
7991
8254
|
return false;
|
|
7992
8255
|
}
|
|
7993
8256
|
/**
|
|
@@ -8043,7 +8306,9 @@ function isBreakingFieldChange(typeName, fieldName, oldField, newField) {
|
|
|
8043
8306
|
if (oldField && newField && oldField.type === "enum" && newField.type === "enum") {
|
|
8044
8307
|
const oldAllowed = oldField.allowedValues ?? [];
|
|
8045
8308
|
const newAllowed = newField.allowedValues ?? [];
|
|
8046
|
-
const
|
|
8309
|
+
const oldValues = oldAllowed.map((v) => v.value);
|
|
8310
|
+
const newValuesSet = new Set(newAllowed.map((v) => v.value));
|
|
8311
|
+
const removedValues = oldValues.filter((v) => !newValuesSet.has(v));
|
|
8047
8312
|
if (removedValues.length > 0) return {
|
|
8048
8313
|
typeName,
|
|
8049
8314
|
fieldName,
|
|
@@ -8099,29 +8364,35 @@ function compareIndexes(ctx, typeName, oldIndexes, newIndexes) {
|
|
|
8099
8364
|
const oldKeys = new Set(Object.keys(oldIndexes || {}));
|
|
8100
8365
|
const newKeys = new Set(Object.keys(newIndexes || {}));
|
|
8101
8366
|
for (const indexName of newKeys) if (!oldKeys.has(indexName)) ctx.changes.push({
|
|
8102
|
-
kind: "
|
|
8367
|
+
kind: "index_added",
|
|
8103
8368
|
typeName,
|
|
8104
|
-
|
|
8105
|
-
|
|
8106
|
-
after: { indexes: newIndexes }
|
|
8369
|
+
indexName,
|
|
8370
|
+
after: newIndexes[indexName]
|
|
8107
8371
|
});
|
|
8108
8372
|
for (const indexName of oldKeys) if (!newKeys.has(indexName)) ctx.changes.push({
|
|
8109
|
-
kind: "
|
|
8373
|
+
kind: "index_removed",
|
|
8110
8374
|
typeName,
|
|
8111
|
-
|
|
8112
|
-
before:
|
|
8113
|
-
after: { indexes: newIndexes }
|
|
8375
|
+
indexName,
|
|
8376
|
+
before: oldIndexes[indexName]
|
|
8114
8377
|
});
|
|
8115
8378
|
for (const indexName of newKeys) if (oldKeys.has(indexName)) {
|
|
8116
8379
|
const oldIndex = oldIndexes[indexName];
|
|
8117
8380
|
const newIndex = newIndexes[indexName];
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
|
|
8123
|
-
|
|
8124
|
-
|
|
8381
|
+
const oldFieldsStr = JSON.stringify(oldIndex.fields.toSorted());
|
|
8382
|
+
const newFieldsStr = JSON.stringify(newIndex.fields.toSorted());
|
|
8383
|
+
if (oldFieldsStr !== newFieldsStr || oldIndex.unique !== newIndex.unique) {
|
|
8384
|
+
const reasons = [];
|
|
8385
|
+
if (oldFieldsStr !== newFieldsStr) reasons.push("fields changed");
|
|
8386
|
+
if (oldIndex.unique !== newIndex.unique) reasons.push("unique constraint changed");
|
|
8387
|
+
ctx.changes.push({
|
|
8388
|
+
kind: "index_modified",
|
|
8389
|
+
typeName,
|
|
8390
|
+
indexName,
|
|
8391
|
+
reason: reasons.join(", "),
|
|
8392
|
+
before: oldIndex,
|
|
8393
|
+
after: newIndex
|
|
8394
|
+
});
|
|
8395
|
+
}
|
|
8125
8396
|
}
|
|
8126
8397
|
}
|
|
8127
8398
|
/**
|
|
@@ -8136,26 +8407,102 @@ function compareFiles(ctx, typeName, oldFiles, newFiles) {
|
|
|
8136
8407
|
const oldKeys = new Set(Object.keys(oldFiles || {}));
|
|
8137
8408
|
const newKeys = new Set(Object.keys(newFiles || {}));
|
|
8138
8409
|
for (const fileName of newKeys) if (!oldKeys.has(fileName)) ctx.changes.push({
|
|
8139
|
-
kind: "
|
|
8410
|
+
kind: "file_added",
|
|
8140
8411
|
typeName,
|
|
8141
|
-
|
|
8142
|
-
|
|
8143
|
-
after: { files: newFiles }
|
|
8412
|
+
fieldName: fileName,
|
|
8413
|
+
after: newFiles[fileName]
|
|
8144
8414
|
});
|
|
8145
8415
|
for (const fileName of oldKeys) if (!newKeys.has(fileName)) ctx.changes.push({
|
|
8146
|
-
kind: "
|
|
8416
|
+
kind: "file_removed",
|
|
8147
8417
|
typeName,
|
|
8148
|
-
|
|
8149
|
-
before:
|
|
8150
|
-
after: { files: newFiles }
|
|
8418
|
+
fieldName: fileName,
|
|
8419
|
+
before: oldFiles[fileName]
|
|
8151
8420
|
});
|
|
8152
8421
|
for (const fileName of newKeys) if (oldKeys.has(fileName)) {
|
|
8153
8422
|
if (oldFiles[fileName] !== newFiles[fileName]) ctx.changes.push({
|
|
8154
|
-
kind: "
|
|
8423
|
+
kind: "file_modified",
|
|
8424
|
+
typeName,
|
|
8425
|
+
fieldName: fileName,
|
|
8426
|
+
reason: "description changed",
|
|
8427
|
+
before: oldFiles[fileName],
|
|
8428
|
+
after: newFiles[fileName]
|
|
8429
|
+
});
|
|
8430
|
+
}
|
|
8431
|
+
}
|
|
8432
|
+
/**
|
|
8433
|
+
* Compare type-level relationships
|
|
8434
|
+
* @param {DiffContext} ctx - Diff context
|
|
8435
|
+
* @param {string} typeName - Type name
|
|
8436
|
+
* @param relationshipType
|
|
8437
|
+
* @param {Record<string, SnapshotRelationship> | undefined} oldRelationships - Previous relationships
|
|
8438
|
+
* @param {Record<string, SnapshotRelationship> | undefined} newRelationships - Current relationships
|
|
8439
|
+
* @returns {void}
|
|
8440
|
+
*/
|
|
8441
|
+
function compareRelationships(ctx, typeName, relationshipType, oldRelationships, newRelationships) {
|
|
8442
|
+
const oldKeys = new Set(Object.keys(oldRelationships || {}));
|
|
8443
|
+
const newKeys = new Set(Object.keys(newRelationships || {}));
|
|
8444
|
+
for (const relName of newKeys) if (!oldKeys.has(relName)) ctx.changes.push({
|
|
8445
|
+
kind: "relationship_added",
|
|
8446
|
+
typeName,
|
|
8447
|
+
relationshipName: relName,
|
|
8448
|
+
relationshipType,
|
|
8449
|
+
after: newRelationships[relName]
|
|
8450
|
+
});
|
|
8451
|
+
for (const relName of oldKeys) if (!newKeys.has(relName)) ctx.changes.push({
|
|
8452
|
+
kind: "relationship_removed",
|
|
8453
|
+
typeName,
|
|
8454
|
+
relationshipName: relName,
|
|
8455
|
+
relationshipType,
|
|
8456
|
+
before: oldRelationships[relName]
|
|
8457
|
+
});
|
|
8458
|
+
for (const relName of newKeys) if (oldKeys.has(relName)) {
|
|
8459
|
+
const oldRel = oldRelationships[relName];
|
|
8460
|
+
const newRel = newRelationships[relName];
|
|
8461
|
+
const reasons = [];
|
|
8462
|
+
if (oldRel.targetType !== newRel.targetType) reasons.push("targetType changed");
|
|
8463
|
+
if (oldRel.targetField !== newRel.targetField) reasons.push("targetField changed");
|
|
8464
|
+
if (oldRel.sourceField !== newRel.sourceField) reasons.push("sourceField changed");
|
|
8465
|
+
if (oldRel.isArray !== newRel.isArray) reasons.push("isArray changed");
|
|
8466
|
+
if (reasons.length > 0) ctx.changes.push({
|
|
8467
|
+
kind: "relationship_modified",
|
|
8468
|
+
typeName,
|
|
8469
|
+
relationshipName: relName,
|
|
8470
|
+
relationshipType,
|
|
8471
|
+
reason: reasons.join(", "),
|
|
8472
|
+
before: oldRel,
|
|
8473
|
+
after: newRel
|
|
8474
|
+
});
|
|
8475
|
+
}
|
|
8476
|
+
}
|
|
8477
|
+
/**
|
|
8478
|
+
* Compare type-level permissions
|
|
8479
|
+
* @param {DiffContext} ctx - Diff context
|
|
8480
|
+
* @param {string} typeName - Type name
|
|
8481
|
+
* @param {SnapshotRecordPermission | undefined} oldRecordPerm - Previous record permission
|
|
8482
|
+
* @param {SnapshotRecordPermission | undefined} newRecordPerm - Current record permission
|
|
8483
|
+
* @param {SnapshotGqlPermission | undefined} oldGqlPerm - Previous GQL permission
|
|
8484
|
+
* @param {SnapshotGqlPermission | undefined} newGqlPerm - Current GQL permission
|
|
8485
|
+
* @returns {void}
|
|
8486
|
+
*/
|
|
8487
|
+
function comparePermissions(ctx, typeName, oldRecordPerm, newRecordPerm, oldGqlPerm, newGqlPerm) {
|
|
8488
|
+
const recordPermChanged = JSON.stringify(oldRecordPerm ?? null) !== JSON.stringify(newRecordPerm ?? null);
|
|
8489
|
+
const gqlPermChanged = JSON.stringify(oldGqlPerm ?? null) !== JSON.stringify(newGqlPerm ?? null);
|
|
8490
|
+
if (recordPermChanged || gqlPermChanged) {
|
|
8491
|
+
const reasons = [];
|
|
8492
|
+
if (recordPermChanged) reasons.push("record permission");
|
|
8493
|
+
if (gqlPermChanged) reasons.push("GQL permission");
|
|
8494
|
+
ctx.changes.push({
|
|
8495
|
+
kind: "permission_modified",
|
|
8155
8496
|
typeName,
|
|
8156
|
-
reason:
|
|
8157
|
-
before: {
|
|
8158
|
-
|
|
8497
|
+
reason: `${reasons.join(" and ")} changed`,
|
|
8498
|
+
before: {
|
|
8499
|
+
recordPermission: oldRecordPerm,
|
|
8500
|
+
gqlPermission: oldGqlPerm
|
|
8501
|
+
},
|
|
8502
|
+
after: {
|
|
8503
|
+
recordPermission: newRecordPerm,
|
|
8504
|
+
gqlPermission: newGqlPerm
|
|
8505
|
+
}
|
|
8159
8506
|
});
|
|
8160
8507
|
}
|
|
8161
8508
|
}
|
|
@@ -8189,6 +8536,9 @@ function compareSnapshots(previous, current) {
|
|
|
8189
8536
|
compareTypeFields(ctx, typeName, prevType, currType);
|
|
8190
8537
|
compareIndexes(ctx, typeName, prevType.indexes, currType.indexes);
|
|
8191
8538
|
compareFiles(ctx, typeName, prevType.files, currType.files);
|
|
8539
|
+
compareRelationships(ctx, typeName, "forward", prevType.forwardRelationships, currType.forwardRelationships);
|
|
8540
|
+
compareRelationships(ctx, typeName, "backward", prevType.backwardRelationships, currType.backwardRelationships);
|
|
8541
|
+
comparePermissions(ctx, typeName, prevType.permissions?.record, currType.permissions?.record, prevType.permissions?.gql, currType.permissions?.gql);
|
|
8192
8542
|
}
|
|
8193
8543
|
return {
|
|
8194
8544
|
version: SCHEMA_SNAPSHOT_VERSION,
|
|
@@ -8294,7 +8644,26 @@ function convertRemoteFieldsToSnapshot(remoteType) {
|
|
|
8294
8644
|
if (remoteField.foreignKeyType) config.foreignKeyType = remoteField.foreignKeyType;
|
|
8295
8645
|
if (remoteField.foreignKeyField) config.foreignKeyField = remoteField.foreignKeyField;
|
|
8296
8646
|
}
|
|
8297
|
-
if (remoteField.allowedValues && remoteField.allowedValues.length > 0) config.allowedValues = remoteField.allowedValues.map((v) =>
|
|
8647
|
+
if (remoteField.allowedValues && remoteField.allowedValues.length > 0) config.allowedValues = remoteField.allowedValues.map((v) => ({
|
|
8648
|
+
value: v.value,
|
|
8649
|
+
...v.description && { description: v.description }
|
|
8650
|
+
}));
|
|
8651
|
+
if (remoteField.description) config.description = remoteField.description;
|
|
8652
|
+
if (remoteField.vector) config.vector = true;
|
|
8653
|
+
if (remoteField.hooks) {
|
|
8654
|
+
config.hooks = {};
|
|
8655
|
+
if (remoteField.hooks.create?.expr) config.hooks.create = { expr: remoteField.hooks.create.expr };
|
|
8656
|
+
if (remoteField.hooks.update?.expr) config.hooks.update = { expr: remoteField.hooks.update.expr };
|
|
8657
|
+
}
|
|
8658
|
+
if (remoteField.validate && remoteField.validate.length > 0) config.validate = remoteField.validate.map((v) => ({
|
|
8659
|
+
script: { expr: v.script?.expr ?? "" },
|
|
8660
|
+
errorMessage: v.errorMessage ?? ""
|
|
8661
|
+
}));
|
|
8662
|
+
if (remoteField.serial) config.serial = {
|
|
8663
|
+
start: Number(remoteField.serial.start),
|
|
8664
|
+
...remoteField.serial.maxValue && { maxValue: Number(remoteField.serial.maxValue) },
|
|
8665
|
+
...remoteField.serial.format && { format: remoteField.serial.format }
|
|
8666
|
+
};
|
|
8298
8667
|
fields[fieldName] = config;
|
|
8299
8668
|
}
|
|
8300
8669
|
return fields;
|
|
@@ -8321,19 +8690,24 @@ function compareFields(typeName, fieldName, remoteField, snapshotField) {
|
|
|
8321
8690
|
const snapshotFk = snapshotField.foreignKey ?? false;
|
|
8322
8691
|
if (remoteFk !== snapshotFk) differences.push(`foreignKey: remote=${remoteFk}, expected=${snapshotFk}`);
|
|
8323
8692
|
if (remoteField.foreignKeyType !== snapshotField.foreignKeyType) differences.push(`foreignKeyType: remote=${remoteField.foreignKeyType ?? "none"}, expected=${snapshotField.foreignKeyType ?? "none"}`);
|
|
8324
|
-
const remoteAllowed =
|
|
8325
|
-
const snapshotAllowed =
|
|
8326
|
-
|
|
8693
|
+
const remoteAllowed = remoteField.allowedValues ?? [];
|
|
8694
|
+
const snapshotAllowed = snapshotField.allowedValues ?? [];
|
|
8695
|
+
const remoteAllowedValues = new Set(remoteAllowed.map((v) => v.value));
|
|
8696
|
+
const snapshotAllowedValues = new Set(snapshotAllowed.map((v) => v.value));
|
|
8697
|
+
if (remoteAllowedValues.size !== snapshotAllowedValues.size) differences.push(`allowedValues count: remote=${remoteAllowedValues.size}, expected=${snapshotAllowedValues.size}`);
|
|
8327
8698
|
else {
|
|
8328
|
-
for (const v of
|
|
8699
|
+
for (const v of remoteAllowedValues) if (!snapshotAllowedValues.has(v)) {
|
|
8329
8700
|
differences.push(`allowedValues: remote has '${v}' not in snapshot`);
|
|
8330
8701
|
break;
|
|
8331
8702
|
}
|
|
8332
|
-
for (const v of
|
|
8703
|
+
for (const v of snapshotAllowedValues) if (!remoteAllowedValues.has(v)) {
|
|
8333
8704
|
differences.push(`allowedValues: snapshot has '${v}' not in remote`);
|
|
8334
8705
|
break;
|
|
8335
8706
|
}
|
|
8336
8707
|
}
|
|
8708
|
+
const remoteVector = remoteField.vector ?? false;
|
|
8709
|
+
const snapshotVector = snapshotField.vector ?? false;
|
|
8710
|
+
if (remoteVector !== snapshotVector) differences.push(`vector: remote=${remoteVector}, expected=${snapshotVector}`);
|
|
8337
8711
|
if (differences.length > 0) return {
|
|
8338
8712
|
typeName,
|
|
8339
8713
|
kind: "field_mismatch",
|
|
@@ -9044,10 +9418,16 @@ function applyPreMigrationFieldAdjustments(fields, typeChanges) {
|
|
|
9044
9418
|
if (!before?.required && after?.required) field.required = false;
|
|
9045
9419
|
if (!(before?.unique ?? false) && (after?.unique ?? false)) field.unique = false;
|
|
9046
9420
|
if (before?.allowedValues && after?.allowedValues) {
|
|
9047
|
-
|
|
9048
|
-
|
|
9049
|
-
|
|
9050
|
-
|
|
9421
|
+
const afterValues = new Set(after.allowedValues.map((v) => v.value));
|
|
9422
|
+
if (before.allowedValues.filter((v) => !afterValues.has(v.value)).length > 0) {
|
|
9423
|
+
const valueMap = /* @__PURE__ */ new Map();
|
|
9424
|
+
for (const v of before.allowedValues) valueMap.set(v.value, v.description ?? "");
|
|
9425
|
+
for (const v of after.allowedValues) if (!valueMap.has(v.value)) valueMap.set(v.value, v.description ?? "");
|
|
9426
|
+
field.allowedValues = Array.from(valueMap.entries()).map(([value, description]) => ({
|
|
9427
|
+
value,
|
|
9428
|
+
description
|
|
9429
|
+
}));
|
|
9430
|
+
}
|
|
9051
9431
|
}
|
|
9052
9432
|
}
|
|
9053
9433
|
}
|
|
@@ -11517,31 +11897,31 @@ const jobsCommand = defineCommand({
|
|
|
11517
11897
|
description: "List or get executor jobs.",
|
|
11518
11898
|
examples: [
|
|
11519
11899
|
{
|
|
11520
|
-
cmd: "
|
|
11900
|
+
cmd: "my-executor",
|
|
11521
11901
|
desc: "List jobs for an executor (default: 50 jobs)"
|
|
11522
11902
|
},
|
|
11523
11903
|
{
|
|
11524
|
-
cmd: "
|
|
11904
|
+
cmd: "my-executor --limit 10",
|
|
11525
11905
|
desc: "Limit the number of jobs"
|
|
11526
11906
|
},
|
|
11527
11907
|
{
|
|
11528
|
-
cmd: "
|
|
11908
|
+
cmd: "my-executor -s RUNNING",
|
|
11529
11909
|
desc: "Filter by status"
|
|
11530
11910
|
},
|
|
11531
11911
|
{
|
|
11532
|
-
cmd: "
|
|
11912
|
+
cmd: "my-executor <job-id>",
|
|
11533
11913
|
desc: "Get job details"
|
|
11534
11914
|
},
|
|
11535
11915
|
{
|
|
11536
|
-
cmd: "
|
|
11916
|
+
cmd: "my-executor <job-id> --attempts",
|
|
11537
11917
|
desc: "Get job details with attempts"
|
|
11538
11918
|
},
|
|
11539
11919
|
{
|
|
11540
|
-
cmd: "
|
|
11920
|
+
cmd: "my-executor <job-id> -W",
|
|
11541
11921
|
desc: "Wait for job to complete"
|
|
11542
11922
|
},
|
|
11543
11923
|
{
|
|
11544
|
-
cmd: "
|
|
11924
|
+
cmd: "my-executor <job-id> -W -l",
|
|
11545
11925
|
desc: "Wait for job with logs"
|
|
11546
11926
|
}
|
|
11547
11927
|
],
|
|
@@ -11769,23 +12149,23 @@ When using \`--wait\`, the CLI tracks not only the executor job but also any dow
|
|
|
11769
12149
|
The \`--logs\` option displays logs from the downstream execution when available.`,
|
|
11770
12150
|
examples: [
|
|
11771
12151
|
{
|
|
11772
|
-
cmd: "
|
|
12152
|
+
cmd: "my-executor",
|
|
11773
12153
|
desc: "Trigger an executor"
|
|
11774
12154
|
},
|
|
11775
12155
|
{
|
|
11776
|
-
cmd: "
|
|
12156
|
+
cmd: "my-executor -d '{\"message\": \"hello\"}'",
|
|
11777
12157
|
desc: "Trigger with data"
|
|
11778
12158
|
},
|
|
11779
12159
|
{
|
|
11780
|
-
cmd: "
|
|
12160
|
+
cmd: "my-executor -d '{\"message\": \"hello\"}' -H \"X-Custom: value\" -H \"X-Another: value2\"",
|
|
11781
12161
|
desc: "Trigger with data and headers"
|
|
11782
12162
|
},
|
|
11783
12163
|
{
|
|
11784
|
-
cmd: "
|
|
12164
|
+
cmd: "my-executor -W",
|
|
11785
12165
|
desc: "Trigger and wait for completion"
|
|
11786
12166
|
},
|
|
11787
12167
|
{
|
|
11788
|
-
cmd: "
|
|
12168
|
+
cmd: "my-executor -W -l",
|
|
11789
12169
|
desc: "Trigger, wait, and show logs"
|
|
11790
12170
|
}
|
|
11791
12171
|
],
|
|
@@ -13181,13 +13561,15 @@ function extractBreakingChangeFields(diff) {
|
|
|
13181
13561
|
optionalToRequired.get(change.typeName).add(change.fieldName);
|
|
13182
13562
|
}
|
|
13183
13563
|
if (before && after && before.type === "enum" && after.type === "enum" && before.allowedValues && after.allowedValues) {
|
|
13184
|
-
const
|
|
13185
|
-
const
|
|
13186
|
-
|
|
13564
|
+
const beforeValues = before.allowedValues.map((v) => v.value);
|
|
13565
|
+
const afterValues = after.allowedValues.map((v) => v.value);
|
|
13566
|
+
const beforeSet = new Set(beforeValues);
|
|
13567
|
+
const afterSet = new Set(afterValues);
|
|
13568
|
+
if (beforeValues.some((v) => !afterSet.has(v)) || afterValues.some((v) => !beforeSet.has(v))) {
|
|
13187
13569
|
if (!enumValueChanges.has(change.typeName)) enumValueChanges.set(change.typeName, /* @__PURE__ */ new Map());
|
|
13188
13570
|
enumValueChanges.get(change.typeName).set(change.fieldName, {
|
|
13189
|
-
beforeValues
|
|
13190
|
-
afterValues
|
|
13571
|
+
beforeValues,
|
|
13572
|
+
afterValues
|
|
13191
13573
|
});
|
|
13192
13574
|
}
|
|
13193
13575
|
}
|
|
@@ -13359,8 +13741,10 @@ function generateFieldType(config, isOptionalToRequired, enumValueChange) {
|
|
|
13359
13741
|
};
|
|
13360
13742
|
let baseType;
|
|
13361
13743
|
let usedTimestamp = false;
|
|
13362
|
-
if (config.type === "enum")
|
|
13363
|
-
|
|
13744
|
+
if (config.type === "enum") {
|
|
13745
|
+
const enumValues = config.allowedValues?.map((v) => v.value) ?? [];
|
|
13746
|
+
baseType = enumValues.length > 0 ? formatEnumUnion(enumValues) : "string";
|
|
13747
|
+
} else {
|
|
13364
13748
|
const mapped = mapToTsType(config.type);
|
|
13365
13749
|
baseType = mapped.type;
|
|
13366
13750
|
usedTimestamp = mapped.usedTimestamp;
|
|
@@ -14871,4 +15255,4 @@ const updateCommand = defineCommand({
|
|
|
14871
15255
|
|
|
14872
15256
|
//#endregion
|
|
14873
15257
|
export { jobsCommand as $, initOperatorClient as $t, generateCommand as A, getMigrationFiles as At, getMachineUserToken as B, generateUserTypes as Bt, resumeCommand as C, compareLocalTypesWithSnapshot as Ct, truncate as D, getLatestMigrationNumber as Dt, listWorkflows as E, formatMigrationNumber as Et, removeCommand$1 as F, formatDiffSummary as Ft, generateCommand$1 as G, fetchLatestToken as Gt, listCommand$5 as H, getDistDir as Ht, listCommand$4 as I, formatMigrationDiff as It, triggerCommand as J, readPlatformConfig as Jt, listWebhookExecutors as K, loadAccessToken as Kt, listOAuth2Clients as L, hasChanges as Lt, show as M, isValidMigrationNumber as Mt, showCommand as N, loadDiff as Nt, truncateCommand as O, getMigrationDirPath as Ot, remove as P, reconstructSnapshotFromMigrations as Pt, getExecutorJob as Q, initOAuth2Client as Qt, getCommand$1 as R, getNamespacesWithMigrations as Rt, healthCommand as S, SCHEMA_FILE_NAME as St, listCommand$3 as T, createSnapshotFromLocalTypes as Tt, listMachineUsers as U, apiCall as Ut, tokenCommand as V, loadConfig as Vt, generate$1 as W, apiCommand as Wt, listCommand$6 as X, fetchAll as Xt, triggerExecutor as Y, writePlatformConfig as Yt, listExecutors as Z, fetchUserInfo as Zt, createCommand as _, bundleMigrationScript as _t, listCommand as a, jsonArgs as an, getWorkflow as at, listCommand$2 as b, INITIAL_SCHEMA_NUMBER as bt, inviteUser as c, listWorkflowExecutions as ct, listCommand$1 as d, apply as dt, readPackageJson as en, listExecutorJobs as et, listWorkspaces as f, applyCommand as ft, deleteWorkspace as g, parseMigrationLabelNumber as gt, deleteCommand as h, MIGRATION_LABEL_KEY as ht, removeUser as i, deploymentArgs as in, getCommand$2 as it, logBetaWarning as j, getNextMigrationNumber as jt, generate as k, getMigrationFilePath as kt, restoreCommand as l, getCommand$3 as lt, getWorkspace as m, waitForExecution$1 as mt, updateUser as n, commonArgs as nn, startCommand as nt, listUsers as o, withCommonArgs as on, executionsCommand as ot, getCommand as p, executeScript as pt, webhookCommand as q, loadWorkspaceId as qt, removeCommand as r, confirmationArgs as rn, startWorkflow as rt, inviteCommand as s, workspaceArgs as sn, getWorkflowExecution as st, updateCommand as t, PATScope as tn, watchExecutorJob as tt, restoreWorkspace as u, getExecutor as ut, createWorkspace as v, DB_TYPES_FILE_NAME as vt, resumeWorkflow as w, compareSnapshots as wt, getAppHealth as x, MIGRATE_FILE_NAME as xt, listApps as y, DIFF_FILE_NAME as yt, getOAuth2Client as z, trnPrefix as zt };
|
|
14874
|
-
//# sourceMappingURL=update-
|
|
15258
|
+
//# sourceMappingURL=update-BnKKm4aR.mjs.map
|