@nyrra/prismantix-cli 0.0.4-next.23 → 0.0.4-next.25
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 +2 -2
- package/dist/foundry-import/actions.d.ts +9 -2
- package/dist/foundry-import/actions.d.ts.map +1 -1
- package/dist/foundry-import/actions.js +436 -19
- package/dist/foundry-import/convert.d.ts.map +1 -1
- package/dist/foundry-import/convert.js +68 -4
- package/dist/foundry-import/emit.d.ts.map +1 -1
- package/dist/foundry-import/emit.js +172 -5
- package/dist/foundry-import/interfaces.d.ts +11 -2
- package/dist/foundry-import/interfaces.d.ts.map +1 -1
- package/dist/foundry-import/interfaces.js +132 -24
- package/dist/foundry-import/names.d.ts +1 -0
- package/dist/foundry-import/names.d.ts.map +1 -1
- package/dist/foundry-import/names.js +18 -0
- package/dist/foundry-import/objects.d.ts +2 -1
- package/dist/foundry-import/objects.d.ts.map +1 -1
- package/dist/foundry-import/objects.js +92 -10
- package/dist/foundry-import/parse.d.ts.map +1 -1
- package/dist/foundry-import/parse.js +520 -0
- package/dist/foundry-import/types.d.ts +78 -5
- package/dist/foundry-import/types.d.ts.map +1 -1
- package/dist/foundry-import/validate.js +15 -3
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ npx -y @nyrra/prismantix-cli download \
|
|
|
43
43
|
|
|
44
44
|
## Foundry Ontology Import
|
|
45
45
|
|
|
46
|
-
Convert a downloaded Foundry ontology export JSON into
|
|
46
|
+
Convert a downloaded Foundry ontology export JSON into an upstream OSDK Ontology-as-Code package:
|
|
47
47
|
|
|
48
48
|
```sh
|
|
49
49
|
npx -y @nyrra/prismantix-cli foundry import \
|
|
@@ -53,4 +53,4 @@ npx -y @nyrra/prismantix-cli foundry import \
|
|
|
53
53
|
--json
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
The command writes generated `.mts` files
|
|
56
|
+
The command writes a package scaffold (`package.json`, `tsconfig.json`), generated `.mts` files, and `diagnostics.json` / `diagnostics.md`. The emitted source targets upstream `@osdk/maker` OAC, not PrismantiX's local `@nyrra/maker` DSL. Use `--validate` to compile the generated source, load it through `@osdk/maker`, and convert it through `@osdk/generator-converters.ontologyir` into full metadata. Dotted or hyphenated Foundry API names are normalized into maker-compatible identifiers and reported in diagnostics.
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
import type { ConversionDiagnostic, FoundryActionType, NormalizedAction } from "./types.js";
|
|
2
|
-
|
|
1
|
+
import type { ConversionDiagnostic, FoundryActionType, NormalizedAction, NormalizedObject } from "./types.js";
|
|
2
|
+
interface ActionNormalizationContext {
|
|
3
|
+
readonly actionNameAllocator: (name: string) => string;
|
|
4
|
+
readonly diagnostics: ConversionDiagnostic[];
|
|
5
|
+
readonly objectsByApiName: ReadonlyMap<string, NormalizedObject>;
|
|
6
|
+
readonly variableNameAllocator: (name: string) => string;
|
|
7
|
+
}
|
|
8
|
+
export declare function normalizeAction(action: FoundryActionType, actionIndex: number, context: ActionNormalizationContext): NormalizedAction | undefined;
|
|
9
|
+
export {};
|
|
3
10
|
//# sourceMappingURL=actions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/foundry-import/actions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"actions.d.ts","sourceRoot":"","sources":["../../src/foundry-import/actions.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACX,oBAAoB,EAIpB,iBAAiB,EAEjB,gBAAgB,EAEhB,gBAAgB,EAChB,MAAM,YAAY,CAAC;AASpB,UAAU,0BAA0B;IACnC,QAAQ,CAAC,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACvD,QAAQ,CAAC,WAAW,EAAE,oBAAoB,EAAE,CAAC;IAC7C,QAAQ,CAAC,gBAAgB,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACjE,QAAQ,CAAC,qBAAqB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACzD;AAED,wBAAgB,eAAe,CAC9B,MAAM,EAAE,iBAAiB,EACzB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,0BAA0B,GACjC,gBAAgB,GAAG,SAAS,CAiC9B"}
|
|
@@ -1,37 +1,454 @@
|
|
|
1
|
-
import { addSanitizationDiagnostic, sanitizeApiName } from "./names.js";
|
|
2
|
-
import { displayNameFor, normalizeStatus, requiredString } from "./utils.js";
|
|
3
|
-
export function normalizeAction(action, actionIndex,
|
|
4
|
-
const apiName = normalizeActionApiName(action, actionIndex,
|
|
1
|
+
import { addSanitizationDiagnostic, createNameAllocator, sanitizeActionApiName, sanitizeApiName, toPascalCase, } from "./names.js";
|
|
2
|
+
import { displayNameFor, isRecord, normalizeDescription, normalizeStatus, requiredString, } from "./utils.js";
|
|
3
|
+
export function normalizeAction(action, actionIndex, context) {
|
|
4
|
+
const apiName = normalizeActionApiName(action, actionIndex, context);
|
|
5
|
+
const parameterNameAllocator = createNameAllocator();
|
|
6
|
+
const parameters = actionFormParameters(action).map((parameter, index) => normalizeActionParameter(parameter, index, actionIndex, parameterNameAllocator, context));
|
|
7
|
+
const rules = normalizeActionRules(action, actionIndex, parameters, context);
|
|
8
|
+
if (rules.length === 0) {
|
|
9
|
+
context.diagnostics.push({
|
|
10
|
+
code: "skipped.actionRules",
|
|
11
|
+
message: `Action ${apiName.original} has no Marketplace-compatible object/interface rules; action was not emitted.`,
|
|
12
|
+
path: `$.actionTypes[${actionIndex}].actionTypeLogic.logic.rules`,
|
|
13
|
+
severity: "warning",
|
|
14
|
+
});
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
5
17
|
return {
|
|
6
18
|
apiName,
|
|
7
19
|
displayName: actionDisplayName(action, apiName.sanitized),
|
|
8
|
-
|
|
9
|
-
ruleTypes:
|
|
10
|
-
|
|
20
|
+
parameters,
|
|
21
|
+
ruleTypes: rules.map(ruleType),
|
|
22
|
+
rules,
|
|
23
|
+
status: actionStatus(action, actionIndex, context.diagnostics),
|
|
24
|
+
variableName: context.variableNameAllocator(`${toPascalCase(apiName.sanitized)}Action`),
|
|
11
25
|
};
|
|
12
26
|
}
|
|
13
|
-
function normalizeActionApiName(action, actionIndex,
|
|
27
|
+
function normalizeActionApiName(action, actionIndex, context) {
|
|
14
28
|
const path = `$.actionTypes[${actionIndex}].metadata.apiName`;
|
|
15
|
-
const original = requiredString(action.metadata?.apiName, path, diagnostics, `action
|
|
16
|
-
const sanitized =
|
|
17
|
-
addSanitizationDiagnostic(diagnostics, path, original, sanitized);
|
|
29
|
+
const original = requiredString(action.metadata?.apiName, path, context.diagnostics, `action-${actionIndex + 1}`);
|
|
30
|
+
const sanitized = context.actionNameAllocator(sanitizeActionApiName(original));
|
|
31
|
+
addSanitizationDiagnostic(context.diagnostics, path, original, sanitized);
|
|
18
32
|
return { original, sanitized };
|
|
19
33
|
}
|
|
20
|
-
function
|
|
21
|
-
return
|
|
34
|
+
function actionFormParameters(action) {
|
|
35
|
+
return (action.metadata?.formContentInOrder ?? []).flatMap((content) => content.type === "parameter" && content.parameter
|
|
36
|
+
? [content.parameter]
|
|
37
|
+
: []);
|
|
22
38
|
}
|
|
23
|
-
function
|
|
24
|
-
|
|
39
|
+
function normalizeActionParameter(parameter, parameterIndex, actionIndex, nameAllocator, context) {
|
|
40
|
+
const path = `$.actionTypes[${actionIndex}].metadata.formContentInOrder[${parameterIndex}].parameter`;
|
|
41
|
+
const original = requiredString(parameter.id, `${path}.id`, context.diagnostics, `parameter${parameterIndex + 1}`);
|
|
42
|
+
const sanitized = nameAllocator(sanitizeApiName(original, "api"));
|
|
43
|
+
addSanitizationDiagnostic(context.diagnostics, `${path}.id`, original, sanitized);
|
|
44
|
+
const mappedType = mapActionParameterType(parameter.type, `${path}.type`, context);
|
|
45
|
+
return {
|
|
46
|
+
description: normalizeDescription(parameter.displayMetadata?.description),
|
|
47
|
+
displayName: displayNameFor(parameter.displayMetadata, sanitized),
|
|
48
|
+
id: { original, sanitized },
|
|
49
|
+
required: parameter.required ?? inferParameterRequired(parameter),
|
|
50
|
+
type: mappedType.type,
|
|
51
|
+
validationAllowedValues: mappedType.allowedValues,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const actionParameterTypeHandlers = {
|
|
55
|
+
ARRAY: mapArrayActionParameterType,
|
|
56
|
+
OBJECT: mapObjectActionParameterType,
|
|
57
|
+
object: mapObjectActionParameterType,
|
|
58
|
+
objectReference: mapObjectActionParameterType,
|
|
59
|
+
objectReferenceList: mapObjectListActionParameterType,
|
|
60
|
+
};
|
|
61
|
+
function mapActionParameterType(baseType, path, context) {
|
|
62
|
+
return actionParameterTypeHandlerFor(baseType?.type)(baseType, path, context);
|
|
63
|
+
}
|
|
64
|
+
function actionParameterTypeHandlerFor(type) {
|
|
65
|
+
return type
|
|
66
|
+
? (actionParameterTypeHandlers[type] ??
|
|
67
|
+
mapScalarOrUnknownActionParameterType)
|
|
68
|
+
: mapDefaultActionParameterType;
|
|
69
|
+
}
|
|
70
|
+
function mapDefaultActionParameterType() {
|
|
71
|
+
return scalarActionParameterType("string", "text");
|
|
72
|
+
}
|
|
73
|
+
function mapScalarOrUnknownActionParameterType(baseType, path, context) {
|
|
74
|
+
if (!baseType?.type) {
|
|
75
|
+
return mapDefaultActionParameterType();
|
|
76
|
+
}
|
|
77
|
+
const type = actionScalarType(baseType.type);
|
|
78
|
+
if (type) {
|
|
79
|
+
return scalarActionParameterType(type, allowedValuesFor(type, baseType));
|
|
80
|
+
}
|
|
81
|
+
context.diagnostics.push({
|
|
82
|
+
code: "coerced.unknownActionParameterType",
|
|
83
|
+
message: `Unknown action parameter type ${String(baseType.type)} emitted as string.`,
|
|
84
|
+
path,
|
|
85
|
+
severity: "warning",
|
|
86
|
+
});
|
|
87
|
+
return scalarActionParameterType("string", "text");
|
|
88
|
+
}
|
|
89
|
+
function mapArrayActionParameterType(baseType, path, context) {
|
|
90
|
+
const mapped = mapActionParameterType(baseType?.subType, `${path}.subType`, context);
|
|
91
|
+
if (typeof mapped.type === "string") {
|
|
92
|
+
return scalarActionParameterType(`${mapped.type}List`, mapped.allowedValues);
|
|
93
|
+
}
|
|
94
|
+
if (isObjectParameterType(mapped.type, "objectReference")) {
|
|
95
|
+
return {
|
|
96
|
+
allowedValues: { type: "objectQuery" },
|
|
97
|
+
type: {
|
|
98
|
+
objectReferenceList: mapped.type.objectReference,
|
|
99
|
+
type: "objectReferenceList",
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
context.diagnostics.push({
|
|
104
|
+
code: "coerced.unsupportedActionParameterListType",
|
|
105
|
+
message: "Unsupported complex action list parameter emitted as stringList.",
|
|
106
|
+
path,
|
|
107
|
+
severity: "warning",
|
|
108
|
+
});
|
|
109
|
+
return scalarActionParameterType("stringList", "text");
|
|
110
|
+
}
|
|
111
|
+
function mapObjectListActionParameterType(baseType, path, context) {
|
|
112
|
+
const mapped = mapObjectActionParameterType(baseType, path, context);
|
|
113
|
+
if (!isObjectParameterType(mapped.type, "objectReference")) {
|
|
114
|
+
return mapped;
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
allowedValues: { type: "objectQuery" },
|
|
118
|
+
type: {
|
|
119
|
+
objectReferenceList: mapped.type.objectReference,
|
|
120
|
+
type: "objectReferenceList",
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function mapObjectActionParameterType(baseType, path, context) {
|
|
125
|
+
const objectType = lookupActionParameterObjectType(baseType, context);
|
|
126
|
+
if (objectType) {
|
|
127
|
+
return objectReferenceActionParameterType(objectType);
|
|
128
|
+
}
|
|
129
|
+
addUnresolvedActionObjectParameterDiagnostic(baseType, path, context);
|
|
130
|
+
return scalarActionParameterType("string", "text");
|
|
131
|
+
}
|
|
132
|
+
function lookupActionParameterObjectType(baseType, context) {
|
|
133
|
+
const objectTypeApiName = baseType
|
|
134
|
+
? objectTypeReferenceApiName(baseType)
|
|
135
|
+
: undefined;
|
|
136
|
+
return objectTypeApiName
|
|
137
|
+
? context.objectsByApiName.get(objectTypeApiName)
|
|
138
|
+
: undefined;
|
|
139
|
+
}
|
|
140
|
+
function addUnresolvedActionObjectParameterDiagnostic(baseType, path, context) {
|
|
141
|
+
context.diagnostics.push({
|
|
142
|
+
code: "coerced.unresolvedActionObjectParameter",
|
|
143
|
+
message: `Action object parameter references missing object ${baseType ? (objectTypeReferenceApiName(baseType) ?? "unknown") : "unknown"}; emitted as string.`,
|
|
144
|
+
path,
|
|
145
|
+
severity: "warning",
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function objectReferenceActionParameterType(objectType) {
|
|
149
|
+
return {
|
|
150
|
+
allowedValues: { type: "objectQuery" },
|
|
151
|
+
type: {
|
|
152
|
+
objectReference: { objectTypeId: objectType.apiName.sanitized },
|
|
153
|
+
type: "objectReference",
|
|
154
|
+
},
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function scalarActionParameterType(type, allowedValues) {
|
|
158
|
+
return {
|
|
159
|
+
allowedValues: typeof allowedValues === "string"
|
|
160
|
+
? { type: allowedValues }
|
|
161
|
+
: allowedValues,
|
|
162
|
+
type,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function actionScalarType(type) {
|
|
166
|
+
const scalarTypes = {
|
|
167
|
+
ATTACHMENT: "attachment",
|
|
168
|
+
BOOLEAN: "boolean",
|
|
169
|
+
DATE: "date",
|
|
170
|
+
DOUBLE: "double",
|
|
171
|
+
GEOHASH: "geohash",
|
|
172
|
+
GEOSHAPE: "geoshape",
|
|
173
|
+
INTEGER: "integer",
|
|
174
|
+
INTEGER_LIST: "integerList",
|
|
175
|
+
LONG: "long",
|
|
176
|
+
LONG_LIST: "longList",
|
|
177
|
+
MARKING: "marking",
|
|
178
|
+
MEDIA_REFERENCE: "mediaReference",
|
|
179
|
+
STRING: "string",
|
|
180
|
+
STRING_LIST: "stringList",
|
|
181
|
+
TIMESTAMP: "timestamp",
|
|
182
|
+
attachment: "attachment",
|
|
183
|
+
attachmentList: "attachmentList",
|
|
184
|
+
boolean: "boolean",
|
|
185
|
+
booleanList: "booleanList",
|
|
186
|
+
date: "date",
|
|
187
|
+
dateList: "dateList",
|
|
188
|
+
double: "double",
|
|
189
|
+
doubleList: "doubleList",
|
|
190
|
+
geohash: "geohash",
|
|
191
|
+
geohashList: "geohashList",
|
|
192
|
+
geopoint: "geohash",
|
|
193
|
+
geoshape: "geoshape",
|
|
194
|
+
geoshapeList: "geoshapeList",
|
|
195
|
+
integer: "integer",
|
|
196
|
+
integerList: "integerList",
|
|
197
|
+
long: "long",
|
|
198
|
+
longList: "longList",
|
|
199
|
+
marking: "marking",
|
|
200
|
+
markingList: "markingList",
|
|
201
|
+
mediaReference: "mediaReference",
|
|
202
|
+
mediaReferenceList: "mediaReferenceList",
|
|
203
|
+
string: "string",
|
|
204
|
+
stringList: "stringList",
|
|
205
|
+
timestamp: "timestamp",
|
|
206
|
+
timestampList: "timestampList",
|
|
207
|
+
};
|
|
208
|
+
return scalarTypes[type];
|
|
209
|
+
}
|
|
210
|
+
function allowedValuesFor(type, baseType) {
|
|
211
|
+
const scalarType = type.endsWith("List")
|
|
212
|
+
? type.slice(0, -"List".length)
|
|
213
|
+
: type;
|
|
214
|
+
const allowedValues = {
|
|
215
|
+
attachment: "attachment",
|
|
216
|
+
boolean: "boolean",
|
|
217
|
+
date: "datetime",
|
|
218
|
+
double: "range",
|
|
219
|
+
geohash: "geohash",
|
|
220
|
+
geoshape: "geoshape",
|
|
221
|
+
integer: "range",
|
|
222
|
+
long: "range",
|
|
223
|
+
mediaReference: "mediaReference",
|
|
224
|
+
string: "text",
|
|
225
|
+
timestamp: "datetime",
|
|
226
|
+
};
|
|
227
|
+
return {
|
|
228
|
+
type: scalarType === "marking"
|
|
229
|
+
? markingAllowedValuesType(baseType)
|
|
230
|
+
: (allowedValues[scalarType] ?? "text"),
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function markingAllowedValuesType(baseType) {
|
|
234
|
+
return baseType.markingType === "CBAC" ? "cbacMarking" : "mandatoryMarking";
|
|
235
|
+
}
|
|
236
|
+
function objectTypeReferenceApiName(baseType) {
|
|
237
|
+
return objectTypeReferenceCandidates(baseType).find((candidate) => typeof candidate === "string");
|
|
238
|
+
}
|
|
239
|
+
function objectTypeReferenceCandidates(baseType) {
|
|
240
|
+
return [
|
|
241
|
+
stringField(baseType, "objectTypeApiName"),
|
|
242
|
+
stringField(baseType, "objectApiName"),
|
|
243
|
+
stringField(baseType, "objectTypeId"),
|
|
244
|
+
nestedObjectTypeReferenceApiName(baseType, "objectReference"),
|
|
245
|
+
nestedObjectTypeReferenceApiName(baseType, "objectReferenceList"),
|
|
246
|
+
];
|
|
247
|
+
}
|
|
248
|
+
function nestedObjectTypeReferenceApiName(baseType, key) {
|
|
249
|
+
const reference = baseType[key];
|
|
250
|
+
return stringField(reference, "objectTypeId");
|
|
25
251
|
}
|
|
26
|
-
function
|
|
27
|
-
|
|
252
|
+
function normalizeActionRules(action, actionIndex, parameters, context) {
|
|
253
|
+
const operations = actionOperations(action);
|
|
254
|
+
return operations.flatMap((operation, operationIndex) => normalizeActionOperation(operation, operationIndex, actionIndex, parameters, context));
|
|
28
255
|
}
|
|
29
|
-
function
|
|
30
|
-
|
|
256
|
+
function actionOperations(action) {
|
|
257
|
+
const explicitOperations = action.operations ?? [];
|
|
258
|
+
return explicitOperations.length > 0
|
|
259
|
+
? explicitOperations
|
|
260
|
+
: actionRules(action).map((rule) => ({
|
|
261
|
+
objectTypeApiName: actionRuleObjectTypeApiName(rule, action),
|
|
262
|
+
type: actionOperationType(rule.type),
|
|
263
|
+
}));
|
|
264
|
+
}
|
|
265
|
+
const actionOperationHandlers = {
|
|
266
|
+
createObject: createObjectOperationRules,
|
|
267
|
+
deleteObject: deleteObjectOperationRules,
|
|
268
|
+
modifyObject: modifyObjectOperationRules,
|
|
269
|
+
};
|
|
270
|
+
function normalizeActionOperation(operation, operationIndex, actionIndex, parameters, context) {
|
|
271
|
+
const path = `$.actionTypes[${actionIndex}].operations[${operationIndex}]`;
|
|
272
|
+
const objectType = actionOperationObjectType(operation, path, context);
|
|
273
|
+
const handler = actionOperationHandler(operation, path, context);
|
|
274
|
+
if (!objectType || !handler) {
|
|
275
|
+
return [];
|
|
276
|
+
}
|
|
277
|
+
return handler(objectType, parameters, path, context);
|
|
278
|
+
}
|
|
279
|
+
function actionOperationObjectType(operation, path, context) {
|
|
280
|
+
const objectType = lookupActionOperationObjectType(operation, context);
|
|
281
|
+
if (objectType) {
|
|
282
|
+
return objectType;
|
|
283
|
+
}
|
|
284
|
+
addSkippedActionOperationDiagnostic(`Action operation ${operation.type ?? "unknown"} references missing object ${operation.objectTypeApiName ?? "unknown"}; operation was not emitted.`, path, context);
|
|
285
|
+
return undefined;
|
|
286
|
+
}
|
|
287
|
+
function lookupActionOperationObjectType(operation, context) {
|
|
288
|
+
return operation.objectTypeApiName
|
|
289
|
+
? context.objectsByApiName.get(operation.objectTypeApiName)
|
|
290
|
+
: undefined;
|
|
291
|
+
}
|
|
292
|
+
function actionOperationHandler(operation, path, context) {
|
|
293
|
+
const handler = operation.type
|
|
294
|
+
? actionOperationHandlers[operation.type]
|
|
295
|
+
: undefined;
|
|
296
|
+
if (!handler) {
|
|
297
|
+
addSkippedActionOperationDiagnostic(`Action operation ${operation.type ?? "unknown"} is not emitted yet.`, path, context);
|
|
298
|
+
}
|
|
299
|
+
return handler;
|
|
300
|
+
}
|
|
301
|
+
function addSkippedActionOperationDiagnostic(message, path, context) {
|
|
302
|
+
context.diagnostics.push({
|
|
303
|
+
code: "skipped.actionOperation",
|
|
304
|
+
message,
|
|
305
|
+
path,
|
|
306
|
+
severity: "warning",
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
function createObjectOperationRules(objectType, parameters) {
|
|
310
|
+
return [createObjectRule(objectType, parameters)];
|
|
311
|
+
}
|
|
312
|
+
function modifyObjectOperationRules(objectType, parameters, path, context) {
|
|
313
|
+
const objectParameter = objectReferenceParameter(parameters, objectType);
|
|
314
|
+
if (!objectParameter) {
|
|
315
|
+
addMissingObjectParameterDiagnostic("Modify", objectType, path, context);
|
|
316
|
+
return [];
|
|
317
|
+
}
|
|
318
|
+
return [modifyObjectRule(objectParameter, objectType, parameters)];
|
|
319
|
+
}
|
|
320
|
+
function deleteObjectOperationRules(objectType, parameters, path, context) {
|
|
321
|
+
const objectParameter = objectReferenceParameter(parameters, objectType);
|
|
322
|
+
if (!objectParameter) {
|
|
323
|
+
addMissingObjectParameterDiagnostic("Delete", objectType, path, context);
|
|
324
|
+
return [];
|
|
325
|
+
}
|
|
326
|
+
return [deleteObjectRule(objectParameter)];
|
|
327
|
+
}
|
|
328
|
+
function addMissingObjectParameterDiagnostic(operationName, objectType, path, context) {
|
|
329
|
+
addSkippedActionOperationDiagnostic(`${operationName} operation for ${objectType.apiName.original} has no object reference parameter; operation was not emitted.`, path, context);
|
|
330
|
+
}
|
|
331
|
+
function createObjectRule(objectType, parameters) {
|
|
332
|
+
return {
|
|
333
|
+
addObjectRule: {
|
|
334
|
+
objectTypeId: objectType.apiName.sanitized,
|
|
335
|
+
propertyValues: propertyValuesFor(objectType, parameters),
|
|
336
|
+
structFieldValues: {},
|
|
337
|
+
},
|
|
338
|
+
type: "addObjectRule",
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
function modifyObjectRule(objectParameter, objectType, parameters) {
|
|
342
|
+
return {
|
|
343
|
+
modifyObjectRule: {
|
|
344
|
+
objectToModify: objectParameter.id.sanitized,
|
|
345
|
+
propertyValues: propertyValuesFor(objectType, parameters),
|
|
346
|
+
structFieldValues: {},
|
|
347
|
+
},
|
|
348
|
+
type: "modifyObjectRule",
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
function deleteObjectRule(objectParameter) {
|
|
352
|
+
return {
|
|
353
|
+
deleteObjectRule: {
|
|
354
|
+
objectToDelete: objectParameter.id.sanitized,
|
|
355
|
+
},
|
|
356
|
+
type: "deleteObjectRule",
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
function propertyValuesFor(objectType, parameters) {
|
|
360
|
+
const objectPropertiesByName = new Map(objectType.properties.flatMap((property) => [
|
|
361
|
+
[property.apiName.original, property.apiName.sanitized],
|
|
362
|
+
[property.apiName.sanitized, property.apiName.sanitized],
|
|
363
|
+
[property.originalId, property.apiName.sanitized],
|
|
364
|
+
]));
|
|
365
|
+
return Object.fromEntries(parameters.flatMap((parameter) => {
|
|
366
|
+
const objectProperty = objectPropertiesByName.get(parameter.id.original) ??
|
|
367
|
+
objectPropertiesByName.get(parameter.id.sanitized);
|
|
368
|
+
return objectProperty
|
|
369
|
+
? [
|
|
370
|
+
[
|
|
371
|
+
objectProperty,
|
|
372
|
+
{ parameterId: parameter.id.sanitized, type: "parameterId" },
|
|
373
|
+
],
|
|
374
|
+
]
|
|
375
|
+
: [];
|
|
376
|
+
}));
|
|
377
|
+
}
|
|
378
|
+
function objectReferenceParameter(parameters, objectType) {
|
|
379
|
+
return parameters.find((parameter) => isObjectParameterType(parameter.type, "objectReference") &&
|
|
380
|
+
parameter.type.objectReference.objectTypeId ===
|
|
381
|
+
objectType.apiName.sanitized);
|
|
382
|
+
}
|
|
383
|
+
function isObjectParameterType(type, expectedType) {
|
|
384
|
+
return (typeof type === "object" &&
|
|
385
|
+
type !== null &&
|
|
386
|
+
stringField(type, "type") === expectedType);
|
|
387
|
+
}
|
|
388
|
+
function actionRuleObjectTypeApiName(rule, action) {
|
|
389
|
+
const ruleBody = ruleBodyFor(rule);
|
|
390
|
+
return (stringField(ruleBody, "objectTypeId") ??
|
|
391
|
+
stringField(ruleBody, "objectTypeApiName") ??
|
|
392
|
+
actionRuleTargetParameterObjectTypeApiName(ruleBody, action));
|
|
393
|
+
}
|
|
394
|
+
function actionRuleTargetParameterObjectTypeApiName(ruleBody, action) {
|
|
395
|
+
const targetParameterId = ["objectToModify", "objectToDelete"]
|
|
396
|
+
.map((field) => stringField(ruleBody, field))
|
|
397
|
+
.find((value) => typeof value === "string");
|
|
398
|
+
const targetParameter = actionFormParameters(action).find((parameter) => parameter.id === targetParameterId);
|
|
399
|
+
return targetParameter?.type
|
|
400
|
+
? objectTypeReferenceApiName(targetParameter.type)
|
|
401
|
+
: undefined;
|
|
402
|
+
}
|
|
403
|
+
function actionOperationType(type) {
|
|
404
|
+
const typeMap = {
|
|
405
|
+
addObjectRule: "createObject",
|
|
406
|
+
addOrModifyObjectRuleV2: "modifyObject",
|
|
407
|
+
deleteObjectRule: "deleteObject",
|
|
408
|
+
modifyObjectRule: "modifyObject",
|
|
409
|
+
};
|
|
410
|
+
return type ? (typeMap[type] ?? type) : undefined;
|
|
411
|
+
}
|
|
412
|
+
function ruleBodyFor(rule) {
|
|
413
|
+
const type = rule.type;
|
|
414
|
+
if (!type) {
|
|
415
|
+
return rule;
|
|
416
|
+
}
|
|
417
|
+
const body = rule[type];
|
|
418
|
+
return typeof body === "object" && body !== null
|
|
419
|
+
? body
|
|
420
|
+
: rule;
|
|
421
|
+
}
|
|
422
|
+
function ruleType(rule) {
|
|
423
|
+
return typeof rule === "object" && rule !== null
|
|
424
|
+
? (stringField(rule, "type") ?? "unknown")
|
|
425
|
+
: "unknown";
|
|
31
426
|
}
|
|
32
427
|
function actionRules(action) {
|
|
33
428
|
return action.actionTypeLogic?.logic?.rules ?? [];
|
|
34
429
|
}
|
|
430
|
+
function actionDisplayName(action, fallback) {
|
|
431
|
+
return displayNameFor(action.metadata?.displayMetadata, fallback);
|
|
432
|
+
}
|
|
35
433
|
function actionStatus(action, actionIndex, diagnostics) {
|
|
36
434
|
return normalizeStatus(action.metadata?.status, `$.actionTypes[${actionIndex}].metadata.status`, diagnostics);
|
|
37
435
|
}
|
|
436
|
+
function inferParameterRequired(parameter) {
|
|
437
|
+
const defaultValidation = recordField(parameter.validation, "defaultValidation");
|
|
438
|
+
const validation = recordField(defaultValidation, "validation");
|
|
439
|
+
return (stringField(recordField(validation, "required"), "type") === "required");
|
|
440
|
+
}
|
|
441
|
+
function recordField(record, key) {
|
|
442
|
+
if (!isRecord(record)) {
|
|
443
|
+
return undefined;
|
|
444
|
+
}
|
|
445
|
+
const value = record[key];
|
|
446
|
+
return isRecord(value) ? value : undefined;
|
|
447
|
+
}
|
|
448
|
+
function stringField(record, key) {
|
|
449
|
+
return typeof record === "object" &&
|
|
450
|
+
record !== null &&
|
|
451
|
+
typeof record[key] === "string"
|
|
452
|
+
? record[key]
|
|
453
|
+
: undefined;
|
|
454
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../src/foundry-import/convert.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEX,gBAAgB,
|
|
1
|
+
{"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../src/foundry-import/convert.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEX,gBAAgB,EAMhB,MAAM,YAAY,CAAC;AAGpB,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAoFvE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { normalizeAction } from "./actions.js";
|
|
2
|
-
import { normalizeInterface } from "./interfaces.js";
|
|
2
|
+
import { addInterfaceReferences, normalizeInterface } from "./interfaces.js";
|
|
3
3
|
import { createNameAllocator } from "./names.js";
|
|
4
4
|
import { normalizeObject } from "./objects.js";
|
|
5
5
|
import { parseFoundryV2Export } from "./parse.js";
|
|
@@ -13,19 +13,47 @@ export function convertFoundryV2Export(input) {
|
|
|
13
13
|
const generalNameAllocator = createNameAllocator();
|
|
14
14
|
const relationNameAllocator = createNameAllocator();
|
|
15
15
|
const variableNameAllocator = createNameAllocator();
|
|
16
|
+
const sharedProperties = foundryExport.sharedProperties.map((sharedProperty, sharedPropertyIndex) => normalizeSharedProperty(sharedProperty, sharedPropertyIndex, generalNameAllocator, variableNameAllocator, diagnostics));
|
|
17
|
+
const sharedPropertiesByOriginalApiName = indexSharedPropertiesByApiName(sharedProperties);
|
|
18
|
+
const sharedPropertiesByRid = indexSharedPropertiesByRid(sharedProperties);
|
|
19
|
+
const interfacesWithoutReferences = foundryExport.interfaces.map((interfaceType, interfaceIndex) => normalizeInterface(interfaceType, interfaceIndex, {
|
|
20
|
+
diagnostics,
|
|
21
|
+
interfaceNameAllocator: generalNameAllocator,
|
|
22
|
+
sharedPropertiesByOriginalApiName,
|
|
23
|
+
sharedPropertiesByRid,
|
|
24
|
+
variableNameAllocator,
|
|
25
|
+
}));
|
|
26
|
+
const interfacesByApiName = indexInterfacesByApiName(interfacesWithoutReferences);
|
|
27
|
+
const interfaces = interfacesWithoutReferences.map((interfaceType, index) => {
|
|
28
|
+
const sourceInterface = foundryExport.interfaces[index];
|
|
29
|
+
return sourceInterface
|
|
30
|
+
? addInterfaceReferences(sourceInterface, interfaceType, index, interfacesByApiName, diagnostics)
|
|
31
|
+
: interfaceType;
|
|
32
|
+
});
|
|
33
|
+
const interfacesWithReferencesByApiName = indexInterfacesByApiName(interfaces);
|
|
16
34
|
const objects = foundryExport.objectTypes.map((objectType, objectIndex) => normalizeObject(objectType, objectIndex, {
|
|
17
35
|
diagnostics,
|
|
36
|
+
interfacesByApiName: interfacesWithReferencesByApiName,
|
|
18
37
|
objectNameAllocator,
|
|
19
38
|
variableNameAllocator,
|
|
20
39
|
}));
|
|
21
40
|
const objectsByRid = indexObjectsByRid(objects);
|
|
41
|
+
const objectsByApiName = indexObjectsByApiName(objects);
|
|
22
42
|
return {
|
|
23
|
-
actions: foundryExport.actionTypes.
|
|
43
|
+
actions: foundryExport.actionTypes.flatMap((action, actionIndex) => {
|
|
44
|
+
const normalized = normalizeAction(action, actionIndex, {
|
|
45
|
+
actionNameAllocator: generalNameAllocator,
|
|
46
|
+
diagnostics,
|
|
47
|
+
objectsByApiName,
|
|
48
|
+
variableNameAllocator,
|
|
49
|
+
});
|
|
50
|
+
return normalized ? [normalized] : [];
|
|
51
|
+
}),
|
|
24
52
|
diagnostics,
|
|
25
|
-
interfaces
|
|
53
|
+
interfaces,
|
|
26
54
|
objects,
|
|
27
55
|
relations: foundryExport.relations.flatMap((relation, relationIndex) => normalizeRelation(relation, relationIndex, objectsByRid, relationNameAllocator, variableNameAllocator, diagnostics)),
|
|
28
|
-
sharedProperties
|
|
56
|
+
sharedProperties,
|
|
29
57
|
sourceVersion: foundryExport.version,
|
|
30
58
|
typeGroups: foundryExport.typeGroups.map(normalizeTypeGroup),
|
|
31
59
|
};
|
|
@@ -39,6 +67,42 @@ function indexObjectsByRid(objects) {
|
|
|
39
67
|
}
|
|
40
68
|
return objectsByRid;
|
|
41
69
|
}
|
|
70
|
+
function indexObjectsByApiName(objects) {
|
|
71
|
+
const objectsByApiName = new Map();
|
|
72
|
+
for (const object of objects) {
|
|
73
|
+
objectsByApiName.set(object.apiName.original, object);
|
|
74
|
+
objectsByApiName.set(object.apiName.sanitized, object);
|
|
75
|
+
if (object.id) {
|
|
76
|
+
objectsByApiName.set(object.id, object);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return objectsByApiName;
|
|
80
|
+
}
|
|
81
|
+
function indexInterfacesByApiName(interfaces) {
|
|
82
|
+
const interfacesByApiName = new Map();
|
|
83
|
+
for (const interfaceType of interfaces) {
|
|
84
|
+
interfacesByApiName.set(interfaceType.apiName.original, interfaceType);
|
|
85
|
+
interfacesByApiName.set(interfaceType.apiName.sanitized, interfaceType);
|
|
86
|
+
}
|
|
87
|
+
return interfacesByApiName;
|
|
88
|
+
}
|
|
89
|
+
function indexSharedPropertiesByApiName(sharedProperties) {
|
|
90
|
+
const sharedPropertiesByApiName = new Map();
|
|
91
|
+
for (const sharedProperty of sharedProperties) {
|
|
92
|
+
sharedPropertiesByApiName.set(sharedProperty.apiName.original, sharedProperty);
|
|
93
|
+
sharedPropertiesByApiName.set(sharedProperty.apiName.sanitized, sharedProperty);
|
|
94
|
+
}
|
|
95
|
+
return sharedPropertiesByApiName;
|
|
96
|
+
}
|
|
97
|
+
function indexSharedPropertiesByRid(sharedProperties) {
|
|
98
|
+
const sharedPropertiesByRid = new Map();
|
|
99
|
+
for (const sharedProperty of sharedProperties) {
|
|
100
|
+
if (sharedProperty.rid) {
|
|
101
|
+
sharedPropertiesByRid.set(sharedProperty.rid, sharedProperty);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return sharedPropertiesByRid;
|
|
105
|
+
}
|
|
42
106
|
function normalizeTypeGroup(typeGroup) {
|
|
43
107
|
return {
|
|
44
108
|
displayName: displayNameFor(typeGroup.displayMetadata, typeGroup.rid ?? "Type Group"),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../src/foundry-import/emit.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEX,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,MAAM,YAAY,CAAC;AAGpB,wBAAgB,sBAAsB,CACrC,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE,WAAgB,GACvB,SAAS,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../src/foundry-import/emit.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEX,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,MAAM,YAAY,CAAC;AAGpB,wBAAgB,sBAAsB,CACrC,MAAM,EAAE,gBAAgB,EACxB,OAAO,GAAE,WAAgB,GACvB,SAAS,WAAW,EAAE,CAsBxB"}
|