intelligent-system-design-language 0.3.13
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/.claude/agents/langium-language-designer.md +38 -0
- package/.claude/agents/typescript-vscode-expert.md +29 -0
- package/.claude/agents/ui-ux-designer.md +36 -0
- package/.claude/settings.local.json +33 -0
- package/.idea/inspectionProfiles/Project_Default.xml +7 -0
- package/.idea/isdl.iml +14 -0
- package/.idea/modules.xml +9 -0
- package/.idea/vcs.xml +7 -0
- package/.idea/watcherTasks.xml +4 -0
- package/.vscodeignore +18 -0
- package/LICENSE +674 -0
- package/README.md +86 -0
- package/bin/cli.js +4 -0
- package/bin/lsp.js +8 -0
- package/isdl.png +0 -0
- package/out/_backgrounds.scss +91 -0
- package/out/_handlebars.scss +505 -0
- package/out/_isdlStyles.scss +1357 -0
- package/out/_vuetifyOverrides.scss +425 -0
- package/out/_vuetifyStyles.scss +31957 -0
- package/out/cli/cli-util.js +39 -0
- package/out/cli/cli-util.js.map +1 -0
- package/out/cli/components/_backgrounds.scss +91 -0
- package/out/cli/components/_handlebars.scss +505 -0
- package/out/cli/components/_isdlStyles.scss +1357 -0
- package/out/cli/components/_vuetifyOverrides.scss +425 -0
- package/out/cli/components/_vuetifyStyles.scss +31957 -0
- package/out/cli/components/active-effect-sheet-generator.js +643 -0
- package/out/cli/components/active-effect-sheet-generator.js.map +1 -0
- package/out/cli/components/base-actor-sheet-generator.js +125 -0
- package/out/cli/components/base-actor-sheet-generator.js.map +1 -0
- package/out/cli/components/base-sheet-generator.js +525 -0
- package/out/cli/components/base-sheet-generator.js.map +1 -0
- package/out/cli/components/chat-card-generator.js +683 -0
- package/out/cli/components/chat-card-generator.js.map +1 -0
- package/out/cli/components/css-generator.js +58 -0
- package/out/cli/components/css-generator.js.map +1 -0
- package/out/cli/components/damage-roll-generator.js +173 -0
- package/out/cli/components/damage-roll-generator.js.map +1 -0
- package/out/cli/components/datamodel-generator.js +672 -0
- package/out/cli/components/datamodel-generator.js.map +1 -0
- package/out/cli/components/derived-data-generator.js +1340 -0
- package/out/cli/components/derived-data-generator.js.map +1 -0
- package/out/cli/components/hotbar-drop-hook-generator.js +95 -0
- package/out/cli/components/hotbar-drop-hook-generator.js.map +1 -0
- package/out/cli/components/init-hook-generator.js +597 -0
- package/out/cli/components/init-hook-generator.js.map +1 -0
- package/out/cli/components/keywords-generator.js +220 -0
- package/out/cli/components/keywords-generator.js.map +1 -0
- package/out/cli/components/language-generator.js +110 -0
- package/out/cli/components/language-generator.js.map +1 -0
- package/out/cli/components/measured-template-preview.js +234 -0
- package/out/cli/components/measured-template-preview.js.map +1 -0
- package/out/cli/components/method-generator.js +1812 -0
- package/out/cli/components/method-generator.js.map +1 -0
- package/out/cli/components/ready-hook-generator.js +448 -0
- package/out/cli/components/ready-hook-generator.js.map +1 -0
- package/out/cli/components/token-generator.js +138 -0
- package/out/cli/components/token-generator.js.map +1 -0
- package/out/cli/components/utils.js +176 -0
- package/out/cli/components/utils.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-attribute.js +148 -0
- package/out/cli/components/vue/base-components/vue-attribute.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-boolean.js +77 -0
- package/out/cli/components/vue/base-components/vue-boolean.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-calculator.js +106 -0
- package/out/cli/components/vue/base-components/vue-calculator.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-damage-application.js +369 -0
- package/out/cli/components/vue/base-components/vue-damage-application.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-damage-bonuses.js +225 -0
- package/out/cli/components/vue/base-components/vue-damage-bonuses.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-damage-resistances.js +256 -0
- package/out/cli/components/vue/base-components/vue-damage-resistances.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-damage-track.js +134 -0
- package/out/cli/components/vue/base-components/vue-damage-track.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-date-time.js +55 -0
- package/out/cli/components/vue/base-components/vue-date-time.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-dice.js +111 -0
- package/out/cli/components/vue/base-components/vue-dice.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-die.js +86 -0
- package/out/cli/components/vue/base-components/vue-die.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-document-choice.js +172 -0
- package/out/cli/components/vue/base-components/vue-document-choice.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-document-choices.js +203 -0
- package/out/cli/components/vue/base-components/vue-document-choices.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-document-link.js +73 -0
- package/out/cli/components/vue/base-components/vue-document-link.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-extended-choice.js +101 -0
- package/out/cli/components/vue/base-components/vue-extended-choice.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-inventory.js +532 -0
- package/out/cli/components/vue/base-components/vue-inventory.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-macro-choice.js +150 -0
- package/out/cli/components/vue/base-components/vue-macro-choice.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-measured-template.js +543 -0
- package/out/cli/components/vue/base-components/vue-measured-template.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-money.js +496 -0
- package/out/cli/components/vue/base-components/vue-money.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-number.js +184 -0
- package/out/cli/components/vue/base-components/vue-number.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-paperdoll.js +56 -0
- package/out/cli/components/vue/base-components/vue-paperdoll.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-parent-property-reference.js +89 -0
- package/out/cli/components/vue/base-components/vue-parent-property-reference.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-prosemirror.js +31 -0
- package/out/cli/components/vue/base-components/vue-prosemirror.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-resource.js +149 -0
- package/out/cli/components/vue/base-components/vue-resource.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-roll-visualizer.js +121 -0
- package/out/cli/components/vue/base-components/vue-roll-visualizer.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-self-property-reference.js +75 -0
- package/out/cli/components/vue/base-components/vue-self-property-reference.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-string-choice.js +111 -0
- package/out/cli/components/vue/base-components/vue-string-choice.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-string-choices.js +216 -0
- package/out/cli/components/vue/base-components/vue-string-choices.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-string.js +73 -0
- package/out/cli/components/vue/base-components/vue-string.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-text-field.js +66 -0
- package/out/cli/components/vue/base-components/vue-text-field.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-tracker.js +444 -0
- package/out/cli/components/vue/base-components/vue-tracker.js.map +1 -0
- package/out/cli/components/vue/vue-action-component-generator.js +88 -0
- package/out/cli/components/vue/vue-action-component-generator.js.map +1 -0
- package/out/cli/components/vue/vue-active-effect-sheet-generator.js +1016 -0
- package/out/cli/components/vue/vue-active-effect-sheet-generator.js.map +1 -0
- package/out/cli/components/vue/vue-base-components-generator.js +59 -0
- package/out/cli/components/vue/vue-base-components-generator.js.map +1 -0
- package/out/cli/components/vue/vue-datatable-component-generator.js +307 -0
- package/out/cli/components/vue/vue-datatable-component-generator.js.map +1 -0
- package/out/cli/components/vue/vue-datatable-sheet-class-generator.js +342 -0
- package/out/cli/components/vue/vue-datatable-sheet-class-generator.js.map +1 -0
- package/out/cli/components/vue/vue-datatable2-component-generator.js +939 -0
- package/out/cli/components/vue/vue-datatable2-component-generator.js.map +1 -0
- package/out/cli/components/vue/vue-document-creation-app.js +140 -0
- package/out/cli/components/vue/vue-document-creation-app.js.map +1 -0
- package/out/cli/components/vue/vue-document-creation-sheet.js +105 -0
- package/out/cli/components/vue/vue-document-creation-sheet.js.map +1 -0
- package/out/cli/components/vue/vue-generator.js +240 -0
- package/out/cli/components/vue/vue-generator.js.map +1 -0
- package/out/cli/components/vue/vue-mixin.js +338 -0
- package/out/cli/components/vue/vue-mixin.js.map +1 -0
- package/out/cli/components/vue/vue-pinned-datatable-component-generator.js +306 -0
- package/out/cli/components/vue/vue-pinned-datatable-component-generator.js.map +1 -0
- package/out/cli/components/vue/vue-prompt-generator.js +201 -0
- package/out/cli/components/vue/vue-prompt-generator.js.map +1 -0
- package/out/cli/components/vue/vue-prompt-sheet-class-generator.js +252 -0
- package/out/cli/components/vue/vue-prompt-sheet-class-generator.js.map +1 -0
- package/out/cli/components/vue/vue-sheet-application-generator.js +2008 -0
- package/out/cli/components/vue/vue-sheet-application-generator.js.map +1 -0
- package/out/cli/components/vue/vue-sheet-class-generator.js +484 -0
- package/out/cli/components/vue/vue-sheet-class-generator.js.map +1 -0
- package/out/cli/generator.js +659 -0
- package/out/cli/generator.js.map +1 -0
- package/out/cli/main.js +43 -0
- package/out/cli/main.js.map +1 -0
- package/out/datatables.min.css +54 -0
- package/out/datatables.min.js +178 -0
- package/out/extension/github/githubAuthProvider.js +345 -0
- package/out/extension/github/githubAuthProvider.js.map +1 -0
- package/out/extension/github/githubConfig.js +132 -0
- package/out/extension/github/githubConfig.js.map +1 -0
- package/out/extension/github/githubGistActions.js +251 -0
- package/out/extension/github/githubGistActions.js.map +1 -0
- package/out/extension/github/githubGistManager.js +255 -0
- package/out/extension/github/githubGistManager.js.map +1 -0
- package/out/extension/github/githubManager.js +1735 -0
- package/out/extension/github/githubManager.js.map +1 -0
- package/out/extension/github/githubQuickActions.js +659 -0
- package/out/extension/github/githubQuickActions.js.map +1 -0
- package/out/extension/github/githubTreeProvider.js +181 -0
- package/out/extension/github/githubTreeProvider.js.map +1 -0
- package/out/extension/github/system-workflow.yml +48 -0
- package/out/extension/main.cjs +70315 -0
- package/out/extension/main.cjs.map +7 -0
- package/out/extension/main.js +237 -0
- package/out/extension/main.js.map +1 -0
- package/out/extension/package.json +426 -0
- package/out/isdl.png +0 -0
- package/out/language/generated/ast.js +2992 -0
- package/out/language/generated/ast.js.map +1 -0
- package/out/language/generated/grammar.js +13970 -0
- package/out/language/generated/grammar.js.map +1 -0
- package/out/language/generated/module.js +20 -0
- package/out/language/generated/module.js.map +1 -0
- package/out/language/intelligent-system-design-language-formatter.js +85 -0
- package/out/language/intelligent-system-design-language-formatter.js.map +1 -0
- package/out/language/intelligent-system-design-language-module.js +69 -0
- package/out/language/intelligent-system-design-language-module.js.map +1 -0
- package/out/language/intelligent-system-design-language-quickfixes.js +37 -0
- package/out/language/intelligent-system-design-language-quickfixes.js.map +1 -0
- package/out/language/intelligent-system-design-language-validator.js +515 -0
- package/out/language/intelligent-system-design-language-validator.js.map +1 -0
- package/out/language/isdl-hover-provider.js +77 -0
- package/out/language/isdl-hover-provider.js.map +1 -0
- package/out/language/isdl-scope-provider.js +149 -0
- package/out/language/isdl-scope-provider.js.map +1 -0
- package/out/language/main.cjs +47655 -0
- package/out/language/main.cjs.map +7 -0
- package/out/language/main.js +11 -0
- package/out/language/main.js.map +1 -0
- package/out/missing-character.png +0 -0
- package/out/package.json +426 -0
- package/out/paperdoll_default.png +0 -0
- package/out/progressbar.min.js +7 -0
- package/out/styles.scss +722 -0
- package/out/test/formatting/formatter.test.js +46 -0
- package/out/test/formatting/formatter.test.js.map +1 -0
- package/out/vuetify.esm.js +30279 -0
- package/package.json +426 -0
|
@@ -0,0 +1,672 @@
|
|
|
1
|
+
import { isActor, isNumberExp, isHtmlExp, isStringExp, isBooleanExp, isResourceExp, isAttributeExp, isDamageTrackExp, isSingleDocumentExp, isNumberParamInitial, isNumberParamMin, isNumberParamMax, isStringParamChoices, isConfigExpression, isStatusProperty, isStatusParamWhen, isDateExp, isTimeExp, isDateTimeExp, isPaperDollExp, isParentPropertyRefExp, isSelfPropertyRefExp, isDocumentChoiceExp, isDocumentChoicesExp, isAction, isVariableExpression, isPrompt, isTrackerExp, isDiceFields, isDieField, isDieInitialParam, isDiceField, isLayout, isMacroField, isMeasuredTemplateField, isLabelParam, isChoiceStringValue, isStringExtendedChoice, isStringChoiceField, isDamageTypeChoiceField, isChoiceCustomProperty, isStringChoicesField, isMoneyField, isDamageTrackTypesParam } from "../../language/generated/ast.js";
|
|
2
|
+
import { expandToNode, joinToNode, toString } from 'langium/generate';
|
|
3
|
+
import * as fs from 'node:fs';
|
|
4
|
+
import * as path from 'node:path';
|
|
5
|
+
import { getAllOfType, toMachineIdentifier } from './utils.js';
|
|
6
|
+
import { translateExpression } from './method-generator.js';
|
|
7
|
+
import { AstUtils } from 'langium';
|
|
8
|
+
export function generateDocumentDataModel(entry, document, destination) {
|
|
9
|
+
const typePath = isActor(document) ? 'actor' : 'item';
|
|
10
|
+
const dataModelPath = path.join(destination, "system", "datamodels", typePath);
|
|
11
|
+
const generatedFilePath = `${path.join(dataModelPath, document.name.toLowerCase())}.mjs`;
|
|
12
|
+
const config = entry.config;
|
|
13
|
+
const id = config.body.find(x => isConfigExpression(x) && x.type == "id").value;
|
|
14
|
+
function generateField(property) {
|
|
15
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
16
|
+
if (isNumberExp(property)) {
|
|
17
|
+
// Check to see if we have literal values for min, initial, and max
|
|
18
|
+
let options = "integer: true";
|
|
19
|
+
const minParam = property.params.find(p => isNumberParamMin(p));
|
|
20
|
+
const maxParam = property.params.find(p => isNumberParamMax(p));
|
|
21
|
+
const initialParam = property.params.find(p => isNumberParamInitial(p));
|
|
22
|
+
if (initialParam && typeof (initialParam.value) === 'number') {
|
|
23
|
+
options += `, initial: ${initialParam.value}`;
|
|
24
|
+
}
|
|
25
|
+
if (minParam && typeof (minParam.value) === 'number') {
|
|
26
|
+
options += `, min: ${minParam.value}`;
|
|
27
|
+
}
|
|
28
|
+
if (maxParam && typeof (maxParam.value) === 'number') {
|
|
29
|
+
options += `, max: ${maxParam.value}`;
|
|
30
|
+
}
|
|
31
|
+
return expandToNode `
|
|
32
|
+
${property.name.toLowerCase()}: new fields.NumberField({${options}}),
|
|
33
|
+
`;
|
|
34
|
+
}
|
|
35
|
+
if (isMoneyField(property)) {
|
|
36
|
+
// Check if this money field has denominations
|
|
37
|
+
if (property.denominations && property.denominations.length > 0) {
|
|
38
|
+
// Multi-denomination money - store as SchemaField with individual denomination fields
|
|
39
|
+
const denominationFields = property.denominations.map(denom => {
|
|
40
|
+
return `${denom.name.toLowerCase()}: new fields.NumberField({initial: 0, nullable: false})`;
|
|
41
|
+
}).join(',\n ');
|
|
42
|
+
return expandToNode `
|
|
43
|
+
${property.name.toLowerCase()}: new fields.SchemaField({
|
|
44
|
+
${denominationFields}
|
|
45
|
+
}),
|
|
46
|
+
`;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
// Single currency money - store as simple NumberField
|
|
50
|
+
const initialParam = property.params.find(p => p.$type === 'NumberParamInitial');
|
|
51
|
+
const initial = (initialParam === null || initialParam === void 0 ? void 0 : initialParam.value) || 0;
|
|
52
|
+
return expandToNode `
|
|
53
|
+
${property.name.toLowerCase()}: new fields.NumberField({initial: ${initial}, nullable: false}),
|
|
54
|
+
`;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (isStringExp(property)) {
|
|
58
|
+
return expandToNode `
|
|
59
|
+
${property.name.toLowerCase()}: new fields.StringField({initial: ""}),
|
|
60
|
+
`;
|
|
61
|
+
}
|
|
62
|
+
if (isStringChoiceField(property)) {
|
|
63
|
+
let choices = property.params.find(p => isStringParamChoices(p));
|
|
64
|
+
function choiceValue(choice) {
|
|
65
|
+
if (!isStringExtendedChoice(choice.value)) {
|
|
66
|
+
return toMachineIdentifier(choice.value);
|
|
67
|
+
}
|
|
68
|
+
let value = choice.value.properties.find(isChoiceStringValue);
|
|
69
|
+
if (value) {
|
|
70
|
+
return toMachineIdentifier(value.value);
|
|
71
|
+
}
|
|
72
|
+
let label = choice.value.properties.find(isLabelParam);
|
|
73
|
+
if (label) {
|
|
74
|
+
return toMachineIdentifier(label.value);
|
|
75
|
+
}
|
|
76
|
+
return "unknown";
|
|
77
|
+
}
|
|
78
|
+
function getDefaultValueForType(type) {
|
|
79
|
+
switch (type) {
|
|
80
|
+
case 'string':
|
|
81
|
+
return '';
|
|
82
|
+
case 'number':
|
|
83
|
+
return 0;
|
|
84
|
+
case 'boolean':
|
|
85
|
+
return false;
|
|
86
|
+
default:
|
|
87
|
+
return null; // or throw an error if you prefer
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// For each extended choice, we need to gather a list of additional custom fields such as bonus: 0 and add them to the datamodel
|
|
91
|
+
let additionalFields = choices.choices.reduce((acc, choice) => {
|
|
92
|
+
if (isStringExtendedChoice(choice.value)) {
|
|
93
|
+
let customProperties = choice.value.properties.filter(isChoiceCustomProperty);
|
|
94
|
+
customProperties.forEach(prop => {
|
|
95
|
+
// Only add if we haven't seen this field name before
|
|
96
|
+
if (!acc.find(field => field.key === prop.key)) {
|
|
97
|
+
acc.push({
|
|
98
|
+
key: prop.key,
|
|
99
|
+
type: typeof prop.value,
|
|
100
|
+
defaultValue: getDefaultValueForType(typeof prop.value)
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return acc;
|
|
106
|
+
}, []);
|
|
107
|
+
if (additionalFields.length > 0) {
|
|
108
|
+
return expandToNode `
|
|
109
|
+
${property.name.toLowerCase()}: new fields.SchemaField({
|
|
110
|
+
value: new fields.StringField({
|
|
111
|
+
choices: [${choices.choices.map(x => `"${choiceValue(x)}"`).join(", ")}],
|
|
112
|
+
initial: "${choiceValue(choices.choices[0])}"
|
|
113
|
+
}),
|
|
114
|
+
icon: new fields.StringField({initial: ""}),
|
|
115
|
+
color: new fields.StringField({initial: "#ffffff"}),
|
|
116
|
+
${joinToNode(additionalFields, field => `${field.key.toLowerCase()}: new fields.${field.type.charAt(0).toUpperCase() + field.type.slice(1)}Field({initial: ${JSON.stringify(field.defaultValue)}})`, { appendNewLineIfNotEmpty: true, separator: ',' })}
|
|
117
|
+
}),
|
|
118
|
+
`;
|
|
119
|
+
}
|
|
120
|
+
return expandToNode `
|
|
121
|
+
${property.name.toLowerCase()}: new fields.SchemaField({
|
|
122
|
+
value: new fields.StringField({
|
|
123
|
+
choices: [${choices.choices.map(x => `"${choiceValue(x)}"`).join(", ")}],
|
|
124
|
+
initial: "${choiceValue(choices.choices[0])}"
|
|
125
|
+
}),
|
|
126
|
+
icon: new fields.StringField({initial: ""}),
|
|
127
|
+
color: new fields.StringField({initial: "#ffffff"})
|
|
128
|
+
}),
|
|
129
|
+
`;
|
|
130
|
+
}
|
|
131
|
+
if (isDamageTypeChoiceField(property)) {
|
|
132
|
+
let choices = property.params.find(p => isStringParamChoices(p));
|
|
133
|
+
function choiceValue(choice) {
|
|
134
|
+
if (!isStringExtendedChoice(choice.value)) {
|
|
135
|
+
return toMachineIdentifier(choice.value);
|
|
136
|
+
}
|
|
137
|
+
let value = choice.value.properties.find(isChoiceStringValue);
|
|
138
|
+
if (value) {
|
|
139
|
+
return toMachineIdentifier(value.value);
|
|
140
|
+
}
|
|
141
|
+
let label = choice.value.properties.find(isLabelParam);
|
|
142
|
+
if (label) {
|
|
143
|
+
return toMachineIdentifier(label.value);
|
|
144
|
+
}
|
|
145
|
+
return "unknown";
|
|
146
|
+
}
|
|
147
|
+
function getDefaultValueForType(type) {
|
|
148
|
+
switch (type) {
|
|
149
|
+
case 'string':
|
|
150
|
+
return '';
|
|
151
|
+
case 'number':
|
|
152
|
+
return 0;
|
|
153
|
+
case 'boolean':
|
|
154
|
+
return false;
|
|
155
|
+
default:
|
|
156
|
+
return null; // or throw an error if you prefer
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// For each extended choice, we need to gather a list of additional custom fields such as bonus: 0 and add them to the datamodel
|
|
160
|
+
let additionalFields = choices.choices.reduce((acc, choice) => {
|
|
161
|
+
if (isStringExtendedChoice(choice.value)) {
|
|
162
|
+
let customProperties = choice.value.properties.filter(isChoiceCustomProperty);
|
|
163
|
+
customProperties.forEach(prop => {
|
|
164
|
+
// Only add if we haven't seen this field name before
|
|
165
|
+
if (!acc.find(field => field.key === prop.key)) {
|
|
166
|
+
acc.push({
|
|
167
|
+
key: prop.key,
|
|
168
|
+
type: typeof prop.value,
|
|
169
|
+
defaultValue: getDefaultValueForType(typeof prop.value)
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
return acc;
|
|
175
|
+
}, []);
|
|
176
|
+
if (additionalFields.length > 0) {
|
|
177
|
+
return expandToNode `
|
|
178
|
+
${property.name.toLowerCase()}: new fields.SchemaField({
|
|
179
|
+
value: new fields.StringField({
|
|
180
|
+
choices: [${choices.choices.map(x => `"${choiceValue(x)}"`).join(", ")}],
|
|
181
|
+
initial: "${choiceValue(choices.choices[0])}"
|
|
182
|
+
}),
|
|
183
|
+
icon: new fields.StringField({initial: ""}),
|
|
184
|
+
color: new fields.StringField({initial: "#ffffff"}),
|
|
185
|
+
${joinToNode(additionalFields, field => `${field.key.toLowerCase()}: new fields.${field.type.charAt(0).toUpperCase() + field.type.slice(1)}Field({initial: ${JSON.stringify(field.defaultValue)}})`, { appendNewLineIfNotEmpty: true, separator: ',' })}
|
|
186
|
+
}),
|
|
187
|
+
`;
|
|
188
|
+
}
|
|
189
|
+
return expandToNode `
|
|
190
|
+
${property.name.toLowerCase()}: new fields.SchemaField({
|
|
191
|
+
value: new fields.StringField({
|
|
192
|
+
choices: [${choices.choices.map(x => `"${choiceValue(x)}"`).join(", ")}],
|
|
193
|
+
initial: "${choiceValue(choices.choices[0])}"
|
|
194
|
+
}),
|
|
195
|
+
icon: new fields.StringField({initial: ""}),
|
|
196
|
+
color: new fields.StringField({initial: "#ffffff"})
|
|
197
|
+
}),
|
|
198
|
+
`;
|
|
199
|
+
}
|
|
200
|
+
if (isStringChoicesField(property)) {
|
|
201
|
+
let choices = property.params.find(p => p.$type === 'StringChoicesParamChoices');
|
|
202
|
+
if (!choices || !choices.choices || choices.choices.length === 0) {
|
|
203
|
+
// Fallback for simple string array if no choices defined
|
|
204
|
+
return expandToNode `
|
|
205
|
+
${property.name.toLowerCase()}: new fields.ArrayField(
|
|
206
|
+
new fields.StringField({}),
|
|
207
|
+
{initial: []}
|
|
208
|
+
),
|
|
209
|
+
`;
|
|
210
|
+
}
|
|
211
|
+
function choiceValue(choice) {
|
|
212
|
+
if (!isStringExtendedChoice(choice.value)) {
|
|
213
|
+
return toMachineIdentifier(choice.value);
|
|
214
|
+
}
|
|
215
|
+
let value = choice.value.properties.find(isChoiceStringValue);
|
|
216
|
+
if (value) {
|
|
217
|
+
return toMachineIdentifier(value.value);
|
|
218
|
+
}
|
|
219
|
+
let label = choice.value.properties.find(isLabelParam);
|
|
220
|
+
if (label) {
|
|
221
|
+
return toMachineIdentifier(label.value);
|
|
222
|
+
}
|
|
223
|
+
return "unknown";
|
|
224
|
+
}
|
|
225
|
+
function getDefaultValueForType(type) {
|
|
226
|
+
switch (type) {
|
|
227
|
+
case 'string':
|
|
228
|
+
return '';
|
|
229
|
+
case 'number':
|
|
230
|
+
return 0;
|
|
231
|
+
case 'boolean':
|
|
232
|
+
return false;
|
|
233
|
+
default:
|
|
234
|
+
return null;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// Check if any choices are extended (have metadata)
|
|
238
|
+
let hasExtendedChoices = choices.choices.some((choice) => isStringExtendedChoice(choice.value));
|
|
239
|
+
if (!hasExtendedChoices) {
|
|
240
|
+
// Simple string choices - use array of strings
|
|
241
|
+
return expandToNode `
|
|
242
|
+
${property.name.toLowerCase()}: new fields.ArrayField(
|
|
243
|
+
new fields.StringField({
|
|
244
|
+
choices: [${choices.choices.map((x) => `"${choiceValue(x)}"`).join(", ")}]
|
|
245
|
+
}),
|
|
246
|
+
{initial: []}
|
|
247
|
+
),
|
|
248
|
+
`;
|
|
249
|
+
}
|
|
250
|
+
// Extended choices - use array of schema objects like choice<string>
|
|
251
|
+
let additionalFields = choices.choices.reduce((acc, choice) => {
|
|
252
|
+
if (isStringExtendedChoice(choice.value)) {
|
|
253
|
+
let customProperties = choice.value.properties.filter(isChoiceCustomProperty);
|
|
254
|
+
customProperties.forEach(prop => {
|
|
255
|
+
// Only add if we haven't seen this field name before
|
|
256
|
+
if (!acc.find(field => field.key === prop.key)) {
|
|
257
|
+
acc.push({
|
|
258
|
+
key: prop.key,
|
|
259
|
+
type: typeof prop.value,
|
|
260
|
+
defaultValue: getDefaultValueForType(typeof prop.value)
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
return acc;
|
|
266
|
+
}, []);
|
|
267
|
+
if (additionalFields.length > 0) {
|
|
268
|
+
return expandToNode `
|
|
269
|
+
${property.name.toLowerCase()}: new fields.ArrayField(
|
|
270
|
+
new fields.SchemaField({
|
|
271
|
+
value: new fields.StringField({
|
|
272
|
+
choices: [${choices.choices.map((x) => `"${choiceValue(x)}"`).join(", ")}]
|
|
273
|
+
}),
|
|
274
|
+
icon: new fields.StringField({initial: ""}),
|
|
275
|
+
color: new fields.StringField({initial: "#ffffff"}),
|
|
276
|
+
${joinToNode(additionalFields, (field) => `${field.key.toLowerCase()}: new fields.${field.type.charAt(0).toUpperCase() + field.type.slice(1)}Field({initial: ${JSON.stringify(field.defaultValue)}})`, { appendNewLineIfNotEmpty: true, separator: ',' })}
|
|
277
|
+
}),
|
|
278
|
+
{initial: []}
|
|
279
|
+
),
|
|
280
|
+
`;
|
|
281
|
+
}
|
|
282
|
+
return expandToNode `
|
|
283
|
+
${property.name.toLowerCase()}: new fields.ArrayField(
|
|
284
|
+
new fields.SchemaField({
|
|
285
|
+
value: new fields.StringField({
|
|
286
|
+
choices: [${choices.choices.map((x) => `"${choiceValue(x)}"`).join(", ")}]
|
|
287
|
+
}),
|
|
288
|
+
icon: new fields.StringField({initial: ""}),
|
|
289
|
+
color: new fields.StringField({initial: "#ffffff"})
|
|
290
|
+
}),
|
|
291
|
+
{initial: []}
|
|
292
|
+
),
|
|
293
|
+
`;
|
|
294
|
+
}
|
|
295
|
+
if (isDateExp(property)) {
|
|
296
|
+
return expandToNode `
|
|
297
|
+
${property.name.toLowerCase()}: new fields.StringField({initial: new Intl.DateTimeFormat('en-CA').format(new Date()) }),
|
|
298
|
+
`;
|
|
299
|
+
}
|
|
300
|
+
if (isTimeExp(property)) {
|
|
301
|
+
return expandToNode `
|
|
302
|
+
${property.name.toLowerCase()}: new fields.StringField({initial: new Date().toTimeString().slice(0, 5) }),
|
|
303
|
+
`;
|
|
304
|
+
}
|
|
305
|
+
if (isDateTimeExp(property)) {
|
|
306
|
+
return expandToNode `
|
|
307
|
+
${property.name.toLowerCase()}: new fields.StringField({initial: new Date().toISOString().slice(0, 16) }),
|
|
308
|
+
`;
|
|
309
|
+
}
|
|
310
|
+
if (isHtmlExp(property)) {
|
|
311
|
+
return expandToNode `
|
|
312
|
+
${property.name.toLowerCase()}: new fields.HTMLField({required: false, blank: true, initial: ""}),
|
|
313
|
+
`;
|
|
314
|
+
}
|
|
315
|
+
if (isBooleanExp(property)) {
|
|
316
|
+
return expandToNode `
|
|
317
|
+
${property.name.toLowerCase()}: new fields.BooleanField(),
|
|
318
|
+
`;
|
|
319
|
+
}
|
|
320
|
+
function getNumberOrNothing(param) {
|
|
321
|
+
if (param && typeof (param.value) === 'number') {
|
|
322
|
+
return param.value;
|
|
323
|
+
}
|
|
324
|
+
return undefined;
|
|
325
|
+
}
|
|
326
|
+
if (isResourceExp(property)) {
|
|
327
|
+
const minParam = property.params.find(p => isNumberParamMin(p));
|
|
328
|
+
const maxParam = property.params.find(p => isNumberParamMax(p));
|
|
329
|
+
const initialParam = property.params.find(p => isNumberParamInitial(p));
|
|
330
|
+
const min = (_a = getNumberOrNothing(minParam)) !== null && _a !== void 0 ? _a : -100;
|
|
331
|
+
const max = (_b = getNumberOrNothing(maxParam)) !== null && _b !== void 0 ? _b : 100;
|
|
332
|
+
const initial = (_c = getNumberOrNothing(initialParam)) !== null && _c !== void 0 ? _c : 0;
|
|
333
|
+
return expandToNode `
|
|
334
|
+
${property.name.toLowerCase()}: new fields.SchemaField({
|
|
335
|
+
value: new fields.NumberField({min: ${min}, initial: ${initial}, integer: true}),
|
|
336
|
+
temp: new fields.NumberField({initial: 0, min: 0, integer: true}),
|
|
337
|
+
max: new fields.NumberField({min: 0, initial: ${max}, integer: true}),
|
|
338
|
+
}),
|
|
339
|
+
`;
|
|
340
|
+
}
|
|
341
|
+
if (isAttributeExp(property)) {
|
|
342
|
+
const minParam = property.params.find(p => isNumberParamMin(p));
|
|
343
|
+
const maxParam = property.params.find(p => isNumberParamMax(p));
|
|
344
|
+
const min = (_d = minParam === null || minParam === void 0 ? void 0 : minParam.value) !== null && _d !== void 0 ? _d : 0;
|
|
345
|
+
const max = (_e = maxParam === null || maxParam === void 0 ? void 0 : maxParam.value) !== null && _e !== void 0 ? _e : 100;
|
|
346
|
+
return expandToNode `
|
|
347
|
+
${property.name.toLowerCase()}: new fields.SchemaField({
|
|
348
|
+
value: new fields.NumberField({integer: true, min: ${min}, initial: ${min}}),
|
|
349
|
+
max: new fields.NumberField({integer: true, min: 0, initial: ${max}}),
|
|
350
|
+
}),
|
|
351
|
+
`;
|
|
352
|
+
}
|
|
353
|
+
if (isTrackerExp(property)) {
|
|
354
|
+
const minParam = property.params.find(p => isNumberParamMin(p));
|
|
355
|
+
const maxParam = property.params.find(p => isNumberParamMax(p));
|
|
356
|
+
const initialParam = property.params.find(p => isNumberParamInitial(p));
|
|
357
|
+
const min = (_f = getNumberOrNothing(minParam)) !== null && _f !== void 0 ? _f : -10;
|
|
358
|
+
const max = (_g = getNumberOrNothing(maxParam)) !== null && _g !== void 0 ? _g : 10;
|
|
359
|
+
const initial = (_h = getNumberOrNothing(initialParam)) !== null && _h !== void 0 ? _h : 0;
|
|
360
|
+
return expandToNode `
|
|
361
|
+
${property.name.toLowerCase()}: new fields.SchemaField({
|
|
362
|
+
min: new fields.NumberField({integer: true, initial: ${min}}),
|
|
363
|
+
value: new fields.NumberField({integer: true, initial: ${initial}}),
|
|
364
|
+
temp: new fields.NumberField({initial: 0, min: 0, integer: true}),
|
|
365
|
+
max: new fields.NumberField({integer: true, min: 0, initial: ${max}}),
|
|
366
|
+
}),
|
|
367
|
+
`;
|
|
368
|
+
}
|
|
369
|
+
if (isDamageTrackExp(property)) {
|
|
370
|
+
const maxParam = property.params.find(x => isNumberParamMax(x));
|
|
371
|
+
const max = (_j = maxParam === null || maxParam === void 0 ? void 0 : maxParam.value) !== null && _j !== void 0 ? _j : 5;
|
|
372
|
+
const typesParam = property.params.find(x => isDamageTrackTypesParam(x));
|
|
373
|
+
const types = (_k = typesParam === null || typesParam === void 0 ? void 0 : typesParam.types) !== null && _k !== void 0 ? _k : [];
|
|
374
|
+
return expandToNode `
|
|
375
|
+
${property.name.toLowerCase()}: new fields.SchemaField({
|
|
376
|
+
empty: new fields.NumberField({initial: ${max}, min: 0, max: ${max}, integer: true}),
|
|
377
|
+
${joinToNode(types, type => `${type}: new fields.NumberField({initial: 0, min: 0, max: ${max}, integer: true}),`, { appendNewLineIfNotEmpty: true })}
|
|
378
|
+
}),
|
|
379
|
+
`;
|
|
380
|
+
}
|
|
381
|
+
if (isSingleDocumentExp(property) || isMacroField(property)) {
|
|
382
|
+
return expandToNode `
|
|
383
|
+
${property.name.toLowerCase()}: new UuidDocumentField(),
|
|
384
|
+
`;
|
|
385
|
+
}
|
|
386
|
+
if (isDocumentChoiceExp(property)) {
|
|
387
|
+
// const multiple = (property.params.find(p => isMultipleParam(p)) as MultipleParam | undefined)?.value ?? false;
|
|
388
|
+
// if (multiple) {
|
|
389
|
+
// return expandToNode`
|
|
390
|
+
// ${property.name.toLowerCase()}: new fields.ArrayField(new UuidDocumentField()),
|
|
391
|
+
// `;
|
|
392
|
+
// }
|
|
393
|
+
return expandToNode `
|
|
394
|
+
${property.name.toLowerCase()}: new UuidDocumentField(),
|
|
395
|
+
`;
|
|
396
|
+
}
|
|
397
|
+
if (isDocumentChoicesExp(property)) {
|
|
398
|
+
return expandToNode `
|
|
399
|
+
${property.name.toLowerCase()}: new UuidDocumentArrayField(),
|
|
400
|
+
`;
|
|
401
|
+
}
|
|
402
|
+
if (isPaperDollExp(property)) {
|
|
403
|
+
function generatePaperDollElementField(property) {
|
|
404
|
+
return expandToNode `
|
|
405
|
+
${property.name.toLowerCase()}: new UuidDocumentField()
|
|
406
|
+
`;
|
|
407
|
+
}
|
|
408
|
+
return expandToNode `
|
|
409
|
+
${property.name.toLowerCase()}: new fields.SchemaField({
|
|
410
|
+
${joinToNode(property.elements, property => generatePaperDollElementField(property), { appendNewLineIfNotEmpty: true, separator: ',' })}
|
|
411
|
+
}),
|
|
412
|
+
`;
|
|
413
|
+
}
|
|
414
|
+
if (isParentPropertyRefExp(property)) {
|
|
415
|
+
console.log(`Parent property ref: ${property.name}`);
|
|
416
|
+
return expandToNode `
|
|
417
|
+
${property.name.toLowerCase()}: new fields.StringField({initial: ""}),
|
|
418
|
+
`;
|
|
419
|
+
}
|
|
420
|
+
if (isSelfPropertyRefExp(property)) {
|
|
421
|
+
console.log(`Self property ref: ${property.name}`);
|
|
422
|
+
return expandToNode `
|
|
423
|
+
${property.name.toLowerCase()}: new fields.StringField({initial: ""}),
|
|
424
|
+
`;
|
|
425
|
+
}
|
|
426
|
+
if (isDiceFields(property)) {
|
|
427
|
+
let initialParam = property.params.find(p => isDieInitialParam(p));
|
|
428
|
+
let initialDie = (_l = initialParam === null || initialParam === void 0 ? void 0 : initialParam.value) !== null && _l !== void 0 ? _l : "d20";
|
|
429
|
+
if (isDieField(property)) {
|
|
430
|
+
return expandToNode `
|
|
431
|
+
${property.name.toLowerCase()}: new fields.StringField({initial: "${initialDie}"}),
|
|
432
|
+
`;
|
|
433
|
+
}
|
|
434
|
+
if (isDiceField(property)) {
|
|
435
|
+
return expandToNode `
|
|
436
|
+
${property.name.toLowerCase()}: new fields.SchemaField({
|
|
437
|
+
die: new fields.StringField({initial: "${initialDie}"}),
|
|
438
|
+
number: new fields.NumberField({integer: true, initial: 0, min: 0}),
|
|
439
|
+
}),
|
|
440
|
+
`;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
if (isMeasuredTemplateField(property)) {
|
|
444
|
+
return expandToNode `
|
|
445
|
+
${property.name.toLowerCase()}: new fields.SchemaField({
|
|
446
|
+
type: new fields.StringField({initial: "circle"}),
|
|
447
|
+
distance: new fields.NumberField({integer: true, initial: 5}),
|
|
448
|
+
direction: new fields.NumberField({integer: true, initial: 0}),
|
|
449
|
+
angle: new fields.NumberField({integer: true, initial: 0}),
|
|
450
|
+
width: new fields.NumberField({integer: true, initial: 0}),
|
|
451
|
+
}),
|
|
452
|
+
`;
|
|
453
|
+
}
|
|
454
|
+
if (isLayout(property)) {
|
|
455
|
+
return joinToNode(property.body, property => generateField(property), { appendNewLineIfNotEmpty: true });
|
|
456
|
+
}
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
function generateCalculatedStatusEffect(property) {
|
|
460
|
+
let whenParam = property.params.find(p => isStatusParamWhen(p));
|
|
461
|
+
if (whenParam == undefined || whenParam.when == undefined)
|
|
462
|
+
return undefined;
|
|
463
|
+
console.log(`Generating calculated status effect for ${property.name}`);
|
|
464
|
+
return expandToNode `
|
|
465
|
+
get ${property.name.toLowerCase()}() {
|
|
466
|
+
return ${translateExpression(entry, id, whenParam === null || whenParam === void 0 ? void 0 : whenParam.when, true, property)};
|
|
467
|
+
}
|
|
468
|
+
`.appendNewLine().appendNewLine();
|
|
469
|
+
}
|
|
470
|
+
function generateStatusEffect(property) {
|
|
471
|
+
return expandToNode `
|
|
472
|
+
get ${property.name.toLowerCase()}() {
|
|
473
|
+
return this.parent.statuses.has("${property.name.toLowerCase()}");
|
|
474
|
+
}
|
|
475
|
+
`;
|
|
476
|
+
}
|
|
477
|
+
let statusEffects = getAllOfType(document.body, isStatusProperty);
|
|
478
|
+
let calculatedStatusEffects = statusEffects.filter(x => x.params.some(p => isStatusParamWhen(p)));
|
|
479
|
+
let nonCalculatedStatusEffects = statusEffects.filter(x => !x.params.some(p => isStatusParamWhen(p)));
|
|
480
|
+
// Name and img come with all docs. We'll go ahead and staple Description on as well
|
|
481
|
+
// Collect all damage types from the entry
|
|
482
|
+
function collectDamageTypes(entry) {
|
|
483
|
+
var _a;
|
|
484
|
+
const damageTypes = new Set();
|
|
485
|
+
// Search through all documents for damage type choice fields
|
|
486
|
+
for (const document of entry.documents) {
|
|
487
|
+
const damageTypeFields = getAllOfType(document.body, isDamageTypeChoiceField);
|
|
488
|
+
for (const field of damageTypeFields) {
|
|
489
|
+
const damageField = field; // Cast to access params
|
|
490
|
+
const choicesParam = (_a = damageField.params) === null || _a === void 0 ? void 0 : _a.find((p) => isStringParamChoices(p));
|
|
491
|
+
if (choicesParam && choicesParam.choices) {
|
|
492
|
+
for (const choice of choicesParam.choices) {
|
|
493
|
+
// Handle simple string choices like "None"
|
|
494
|
+
if (typeof choice.value === 'string') {
|
|
495
|
+
damageTypes.add(choice.value);
|
|
496
|
+
}
|
|
497
|
+
// Handle extended choices like { label: "🔥Fire", value: "Fire", ... }
|
|
498
|
+
else if (choice.value && typeof choice.value === 'object') {
|
|
499
|
+
const extendedChoice = choice.value;
|
|
500
|
+
// Try direct access to value property first
|
|
501
|
+
if (extendedChoice.value && typeof extendedChoice.value === 'string') {
|
|
502
|
+
damageTypes.add(extendedChoice.value);
|
|
503
|
+
}
|
|
504
|
+
// Try properties array access
|
|
505
|
+
else if (extendedChoice.properties && Array.isArray(extendedChoice.properties)) {
|
|
506
|
+
// Based on the ISDL syntax { label: "🔥Fire", value: "Fire", icon: "...", color: "...", ... }
|
|
507
|
+
// Property 0 = label, Property 1 = value, Property 2 = icon, Property 3 = color, rest = custom
|
|
508
|
+
if (extendedChoice.properties.length > 1 && extendedChoice.properties[1].value) {
|
|
509
|
+
const damageTypeValue = extendedChoice.properties[1].value;
|
|
510
|
+
damageTypes.add(damageTypeValue);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
return Array.from(damageTypes).sort();
|
|
519
|
+
}
|
|
520
|
+
// Generate damage type fields for Active Effects
|
|
521
|
+
function generateDamageTypeFields(entry) {
|
|
522
|
+
const damageTypes = collectDamageTypes(entry);
|
|
523
|
+
if (damageTypes.length === 0) {
|
|
524
|
+
return expandToNode ``;
|
|
525
|
+
}
|
|
526
|
+
const damageTypeFields = damageTypes.map(damageType => {
|
|
527
|
+
const safeTypeName = damageType.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
528
|
+
return expandToNode `
|
|
529
|
+
// ${damageType} damage type fields
|
|
530
|
+
${safeTypeName}bonusdamage: new fields.NumberField({required: false, initial: 0, integer: true}),
|
|
531
|
+
${safeTypeName}damageresistanceflat: new fields.NumberField({required: false, initial: 0, integer: true}),
|
|
532
|
+
${safeTypeName}damageresistancepercent: new fields.NumberField({required: false, initial: 0, min: 0, max: 100, integer: true}),
|
|
533
|
+
`;
|
|
534
|
+
});
|
|
535
|
+
return expandToNode `
|
|
536
|
+
// Auto-generated damage type Active Effect fields
|
|
537
|
+
${joinToNode(damageTypeFields, field => field, { appendNewLineIfNotEmpty: true })}
|
|
538
|
+
`;
|
|
539
|
+
}
|
|
540
|
+
const fileNode = expandToNode `
|
|
541
|
+
import ${config.name}Actor from "../../documents/actor.mjs";
|
|
542
|
+
import ${config.name}Item from "../../documents/item.mjs";
|
|
543
|
+
import UuidDocumentField from "../UuidDocumentField.mjs";
|
|
544
|
+
import UuidDocumentArrayField from "../UuidDocumentArrayField.mjs";
|
|
545
|
+
|
|
546
|
+
export default class ${document.name}TypeDataModel extends foundry.abstract.DataModel {
|
|
547
|
+
/** @inheritDoc */
|
|
548
|
+
static defineSchema() {
|
|
549
|
+
const fields = foundry.data.fields;
|
|
550
|
+
return {
|
|
551
|
+
description: new fields.HTMLField({required: false, blank: true, initial: ""}),
|
|
552
|
+
${joinToNode(document.body, property => generateField(property), { appendNewLineIfNotEmpty: true })}
|
|
553
|
+
${expandToNode `${generateDocumentPromptModels(document)}`.appendNewLineIfNotEmpty()}
|
|
554
|
+
${isActor(document) ? expandToNode `${generateDamageTypeFields(entry)}`.appendNewLineIfNotEmpty() : ""}
|
|
555
|
+
${!isActor(document) ? "pinned: new fields.BooleanField({initial: false})," : ""}
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/* -------------------------------------------- */
|
|
560
|
+
|
|
561
|
+
${joinToNode(calculatedStatusEffects, effect => generateCalculatedStatusEffect(effect), { appendNewLineIfNotEmpty: true })}
|
|
562
|
+
${joinToNode(nonCalculatedStatusEffects, effect => generateStatusEffect(effect), { appendNewLineIfNotEmpty: true })}
|
|
563
|
+
};
|
|
564
|
+
`.appendNewLineIfNotEmpty();
|
|
565
|
+
if (!fs.existsSync(dataModelPath)) {
|
|
566
|
+
fs.mkdirSync(dataModelPath, { recursive: true });
|
|
567
|
+
}
|
|
568
|
+
fs.writeFileSync(generatedFilePath, toString(fileNode));
|
|
569
|
+
function generateDocumentPromptModels(document) {
|
|
570
|
+
const actions = getAllOfType(document.body, isAction, false);
|
|
571
|
+
return joinToNode(actions.map(x => generatePromptModels(x, document)).filter(x => x !== undefined).map(x => x), { appendNewLineIfNotEmpty: true });
|
|
572
|
+
}
|
|
573
|
+
function generatePromptModels(action, document) {
|
|
574
|
+
const variables = action.method.body.filter(x => isVariableExpression(x));
|
|
575
|
+
const prompts = variables.filter(x => isPrompt(x.value)).map(x => x.value);
|
|
576
|
+
return joinToNode(prompts.map(p => generatePromptModel(p)), { appendNewLineIfNotEmpty: true });
|
|
577
|
+
}
|
|
578
|
+
function generatePromptModel(prompt) {
|
|
579
|
+
const variable = AstUtils.getContainerOfType(prompt.$container, isVariableExpression);
|
|
580
|
+
const action = AstUtils.getContainerOfType(prompt.$container, isAction);
|
|
581
|
+
return expandToNode `
|
|
582
|
+
${action === null || action === void 0 ? void 0 : action.name.toLowerCase()}${variable === null || variable === void 0 ? void 0 : variable.name.toLowerCase()}: new foundry.data.fields.SchemaField({
|
|
583
|
+
${joinToNode(prompt.body, property => generateField(property), { appendNewLineIfNotEmpty: true })}
|
|
584
|
+
}),
|
|
585
|
+
`;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
export function generateUuidDocumentField(destination) {
|
|
589
|
+
const dataModelPath = path.join(destination, "system", "datamodels");
|
|
590
|
+
const generatedFilePath = path.join(dataModelPath, "UuidDocumentField.mjs");
|
|
591
|
+
const fileNode = expandToNode `
|
|
592
|
+
export default class UuidDocumentField extends foundry.data.fields.StringField {
|
|
593
|
+
|
|
594
|
+
/** @inheritdoc */
|
|
595
|
+
static get _defaults() {
|
|
596
|
+
return foundry.utils.mergeObject(super._defaults, {
|
|
597
|
+
required: true,
|
|
598
|
+
blank: false,
|
|
599
|
+
nullable: true,
|
|
600
|
+
initial: null,
|
|
601
|
+
readonly: false,
|
|
602
|
+
validationError: "is not a valid Document UUID string"
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/** @override */
|
|
607
|
+
_cast(value) {
|
|
608
|
+
if ( value instanceof foundry.abstract.Document ) return value.uuid;
|
|
609
|
+
else return String(value);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/** @inheritdoc */
|
|
613
|
+
initialize(value, model, options={}) {
|
|
614
|
+
if ( !game.collections ) return value; // server-side
|
|
615
|
+
|
|
616
|
+
return () => fromUuidSync(value);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
`.appendNewLineIfNotEmpty();
|
|
620
|
+
if (!fs.existsSync(dataModelPath)) {
|
|
621
|
+
fs.mkdirSync(dataModelPath, { recursive: true });
|
|
622
|
+
}
|
|
623
|
+
fs.writeFileSync(generatedFilePath, toString(fileNode));
|
|
624
|
+
}
|
|
625
|
+
export function generateUuidDocumentArrayField(destination) {
|
|
626
|
+
const dataModelPath = path.join(destination, "system", "datamodels");
|
|
627
|
+
const generatedFilePath = path.join(dataModelPath, "UuidDocumentArrayField.mjs");
|
|
628
|
+
const fileNode = expandToNode `
|
|
629
|
+
export default class UuidDocumentArrayField extends foundry.data.fields.ArrayField {
|
|
630
|
+
|
|
631
|
+
constructor(options = {}) {
|
|
632
|
+
super(new foundry.data.fields.StringField({
|
|
633
|
+
required: false,
|
|
634
|
+
blank: false,
|
|
635
|
+
nullable: false,
|
|
636
|
+
initial: null,
|
|
637
|
+
readonly: false,
|
|
638
|
+
validationError: "is not a valid Document UUID string"
|
|
639
|
+
}), foundry.utils.mergeObject({
|
|
640
|
+
initial: []
|
|
641
|
+
}, options));
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/** @override */
|
|
645
|
+
_cast(value) {
|
|
646
|
+
if (!Array.isArray(value)) return [];
|
|
647
|
+
return value.map(item => {
|
|
648
|
+
if (item instanceof foundry.abstract.Document) return item.uuid;
|
|
649
|
+
return String(item);
|
|
650
|
+
}).filter(uuid => uuid && uuid !== "null" && uuid !== "undefined");
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/** @inheritdoc */
|
|
654
|
+
initialize(value, model, options={}) {
|
|
655
|
+
if (!game.collections) return value; // server-side
|
|
656
|
+
if (!Array.isArray(value)) return [];
|
|
657
|
+
|
|
658
|
+
return () => {
|
|
659
|
+
return value.map(uuid => {
|
|
660
|
+
if (!uuid || uuid === "null" || uuid === "undefined") return null;
|
|
661
|
+
return fromUuidSync(uuid);
|
|
662
|
+
}).filter(Boolean);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
`.appendNewLineIfNotEmpty();
|
|
667
|
+
if (!fs.existsSync(dataModelPath)) {
|
|
668
|
+
fs.mkdirSync(dataModelPath, { recursive: true });
|
|
669
|
+
}
|
|
670
|
+
fs.writeFileSync(generatedFilePath, toString(fileNode));
|
|
671
|
+
}
|
|
672
|
+
//# sourceMappingURL=datamodel-generator.js.map
|