dazscript-framework 0.1.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.
Files changed (67) hide show
  1. package/babel/babel.config.js +33 -0
  2. package/babel/trace-babel-plugin.js +243 -0
  3. package/babel/trace-log-babel-plugin.js +164 -0
  4. package/common/core.ts +2 -0
  5. package/common/log.ts +57 -0
  6. package/common/trace.ts +26 -0
  7. package/core/action-decorator.ts +16 -0
  8. package/dialog/basic-dialog.ts +32 -0
  9. package/dialog/builders/button-builder.ts +53 -0
  10. package/dialog/builders/checkbox-builder.ts +30 -0
  11. package/dialog/builders/combo-box-builder.ts +36 -0
  12. package/dialog/builders/combo-edit-builder.ts +36 -0
  13. package/dialog/builders/dialog-builder.ts +49 -0
  14. package/dialog/builders/groupbox-builder.ts +73 -0
  15. package/dialog/builders/label-builder.ts +18 -0
  16. package/dialog/builders/layout-builder.ts +46 -0
  17. package/dialog/builders/line-edit-builder.ts +118 -0
  18. package/dialog/builders/list-view-builder.ts +327 -0
  19. package/dialog/builders/node-selection-builder.ts +44 -0
  20. package/dialog/builders/popup-menu-builder.ts +47 -0
  21. package/dialog/builders/radio-builder.ts +43 -0
  22. package/dialog/builders/splitter-builder.ts +90 -0
  23. package/dialog/builders/tab-builder.ts +106 -0
  24. package/dialog/builders/widget-builder.ts +109 -0
  25. package/dialog/builders/widgets-builder.ts +119 -0
  26. package/dialog/input-dialog.ts +28 -0
  27. package/dialog/input-validator.ts +9 -0
  28. package/dialog/shared.ts +8 -0
  29. package/helpers/action-helper.ts +81 -0
  30. package/helpers/array-helper.ts +145 -0
  31. package/helpers/camera-helper.ts +14 -0
  32. package/helpers/custom-action-helper.ts +176 -0
  33. package/helpers/file-helper.ts +90 -0
  34. package/helpers/input-helper.ts +19 -0
  35. package/helpers/list-view-helper.ts +89 -0
  36. package/helpers/menu-helper.ts +29 -0
  37. package/helpers/message-box-helper.ts +16 -0
  38. package/helpers/node-helper.ts +216 -0
  39. package/helpers/number-helper.ts +11 -0
  40. package/helpers/numeric-property-helper.ts +92 -0
  41. package/helpers/object-helper.ts +3 -0
  42. package/helpers/pane-helper.ts +21 -0
  43. package/helpers/progress-helper.ts +34 -0
  44. package/helpers/property-helper.ts +53 -0
  45. package/helpers/record-helper.ts +16 -0
  46. package/helpers/scene-helper.ts +96 -0
  47. package/helpers/script-helper.ts +16 -0
  48. package/helpers/skeleton-helper.ts +27 -0
  49. package/helpers/splitter-helper.ts +9 -0
  50. package/helpers/string-helper.ts +28 -0
  51. package/helpers/surface-helper.ts +6 -0
  52. package/helpers/undo-helper.ts +7 -0
  53. package/helpers/viewport-helper.ts +9 -0
  54. package/lib/delayed.ts +39 -0
  55. package/lib/dz-dump.ts +121 -0
  56. package/lib/global.ts +5 -0
  57. package/lib/guid.ts +3 -0
  58. package/lib/observable.ts +94 -0
  59. package/lib/set.ts +25 -0
  60. package/lib/settings.ts +104 -0
  61. package/models/custom-action.ts +12 -0
  62. package/models/frame-keys.ts +68 -0
  63. package/package.json +48 -0
  64. package/shared/base-script.ts +30 -0
  65. package/shared/install-generator.js +185 -0
  66. package/shared/set-keyboard-shortcut.ts +103 -0
  67. package/webpack.config.js +48 -0
@@ -0,0 +1,185 @@
1
+ const tsFileParser = require('ts-file-parser');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const glob = require('glob');
5
+ const { program } = require('commander');
6
+
7
+ program
8
+ .requiredOption(
9
+ '-p, --scriptsPath <path>',
10
+ 'Specify the path to your scripts'
11
+ )
12
+ .option(
13
+ '-m, --defaultMenuPath [path]',
14
+ 'Specify the default menu path',
15
+ 'My Scripts'
16
+ )
17
+ .parse(process.argv);
18
+ let options = program.opts();
19
+
20
+ const nameofActionDecorator = 'action';
21
+
22
+ const scriptsPath = options.scriptsPath.endsWith('/')
23
+ ? options.scriptsPath
24
+ : options.scriptsPath + '/';
25
+ const defaultMenuPath = options.defaultMenuPath.endsWith('/')
26
+ ? options.defaultMenuPath
27
+ : options.defaultMenuPath + '/';
28
+
29
+ const container = { scripts: [] };
30
+
31
+ function getPartialPath(filePath) {
32
+ const fileInfo = path.parse(filePath);
33
+ const dir = fileInfo.dir.replace('/src', '').replace(/^\.\//, '');
34
+ return `${dir}/${fileInfo.name}`;
35
+ }
36
+
37
+ function compareStrings(a, b) {
38
+ return a.localeCompare(b, undefined, { sensitivity: 'base' });
39
+ }
40
+
41
+ function stringOrDefault(str, defaultValue) {
42
+ return str !== undefined && str !== null && str !== '' ? str : defaultValue;
43
+ }
44
+
45
+ function generateInstallerTemplate(data) {
46
+ return `
47
+ import { installCustomActions as install } from '@dsf/helpers/custom-action-helper';
48
+
49
+ install(${data});
50
+ `;
51
+ }
52
+
53
+ function generateUninstallerTemplate(data) {
54
+ return `
55
+ import { uninstallCustomActions as uninstall } from '@dsf/helpers/custom-action-helper';
56
+
57
+ uninstall(${data});
58
+ `;
59
+ }
60
+
61
+ function processScript(filePath) {
62
+ const fileInfo = path.parse(filePath);
63
+ const content = fs.readFileSync(filePath, 'utf-8').toString();
64
+ const json = tsFileParser.parseStruct(content, {}, filePath);
65
+
66
+ json.classes.forEach((cls) => {
67
+ const actionDecorator = cls.decorators.find(
68
+ (d) => d.name === nameofActionDecorator
69
+ );
70
+
71
+ if (!actionDecorator) return;
72
+
73
+ const decorator = actionDecorator.arguments[0] ?? {};
74
+
75
+ const script = {
76
+ name: null,
77
+ text: fileInfo.name.replace('.dsa', ''),
78
+ filePath:
79
+ decorator.bundle === undefined
80
+ ? getPartialPath(filePath)
81
+ : fileInfo.name.replace('.ts', ''),
82
+ menuPath: `${defaultMenuPath}${path.parse(getPartialPath(filePath)).dir}`,
83
+ description: fileInfo.name.replace('.dsa', ''),
84
+ group: stringOrDefault(decorator.group, undefined),
85
+ shortcut: stringOrDefault(decorator.shortcut),
86
+ toolbar: stringOrDefault(decorator.toolbar, undefined),
87
+ };
88
+
89
+ const icon = filePath.replace('.ts', '.png');
90
+ if (fs.existsSync(icon)) {
91
+ script.icon =
92
+ decorator.bundle === undefined
93
+ ? `${getPartialPath(filePath)}.png`
94
+ : fileInfo.name.replace('.dsa', '.dsa.png');
95
+ }
96
+
97
+ if (actionDecorator) {
98
+ script.text = stringOrDefault(decorator.text, script.text);
99
+ if (typeof decorator.menuPath === 'boolean') {
100
+ script.menuPath = decorator.menuPath === true ? script.menuPath : '';
101
+ } else {
102
+ script.menuPath = stringOrDefault(decorator.menuPath, script.menuPath);
103
+ }
104
+ script.menuPath = script.menuPath.replace(
105
+ '#{defaultMenuPath}',
106
+ defaultMenuPath
107
+ );
108
+ script.shortcut = decorator.shortcut;
109
+ }
110
+
111
+ console.log(`Adding script: ${script.text}`, script);
112
+ container.scripts.push(script);
113
+
114
+ // Check if the decorator has a "bundle" property
115
+ if (decorator.bundle !== undefined) {
116
+ let packageInstallerFilePath = `Install.dsa.ts`;
117
+ let packageUninstallerFilePath = `Uninstall.dsa.ts`;
118
+
119
+ if (decorator.bundle !== true) {
120
+ // If decorator.bundle is a string, use it as the bundle file name
121
+ packageInstallerFilePath = `Install ${decorator.bundle}.dsa.ts`;
122
+ packageUninstallerFilePath = `Uninstall ${decorator.bundle}.dsa.ts`;
123
+ }
124
+
125
+ // Generate a separate file with the specified or default name
126
+ let bundleScriptContent = generateInstallerTemplate(
127
+ JSON.stringify(container.scripts, null, 4)
128
+ );
129
+ let bundleScriptFilePath = path.join(
130
+ path.parse(filePath).dir,
131
+ packageInstallerFilePath
132
+ );
133
+ fs.writeFileSync(bundleScriptFilePath, bundleScriptContent);
134
+
135
+ bundleScriptContent = generateUninstallerTemplate(
136
+ JSON.stringify(container.scripts, null, 4)
137
+ );
138
+ bundleScriptFilePath = path.join(
139
+ path.parse(filePath).dir,
140
+ packageUninstallerFilePath
141
+ );
142
+ fs.writeFileSync(bundleScriptFilePath, bundleScriptContent);
143
+ }
144
+ });
145
+ }
146
+
147
+ function processScripts(paths) {
148
+ paths.forEach((filePath) => {
149
+ console.log(`Processing ${filePath}`);
150
+ processScript(filePath);
151
+ });
152
+ }
153
+
154
+ function generate() {
155
+ glob(`${scriptsPath}/**/*.dsa.ts`, function (err, paths) {
156
+ if (err) {
157
+ console.error('Error while globbing:', err);
158
+ return;
159
+ }
160
+
161
+ processScripts(paths);
162
+
163
+ container.scripts = container.scripts.sort((a, b) => {
164
+ const aKey = a.menuPath + a.filePath;
165
+ const bKey = b.menuPath + b.filePath;
166
+ return compareStrings(aKey, bKey);
167
+ });
168
+
169
+ // Generate the InstallerScript class and call install function
170
+ const installerScriptContent = generateInstallerTemplate(
171
+ JSON.stringify(container.scripts, null, 4)
172
+ );
173
+ let outputFilePath = './src/Install.dsa.ts';
174
+ fs.writeFileSync(outputFilePath, installerScriptContent);
175
+
176
+ const uninstallerScriptContent = generateUninstallerTemplate(
177
+ JSON.stringify(container.scripts, null, 4)
178
+ );
179
+ outputFilePath = './src/Uninstall.dsa.ts';
180
+ fs.writeFileSync(outputFilePath, uninstallerScriptContent);
181
+ });
182
+ }
183
+
184
+ // Call the generate function at the end of the script
185
+ generate();
@@ -0,0 +1,103 @@
1
+ import { BasicDialog } from '@dsf/dialog/basic-dialog';
2
+ import { setActionShortcut } from '@dsf/helpers/action-helper';
3
+ import { contains } from '@dsf/helpers/array-helper';
4
+ import { Observable } from '@dsf/lib/observable';
5
+
6
+ class KeyboardShortcutModel {
7
+ actionLabel: string
8
+ shortcut = new Observable('')
9
+ control = new Observable(false)
10
+ alt = new Observable(false)
11
+ shift = new Observable(false)
12
+ windows = new Observable(false)
13
+ }
14
+
15
+ const letters = [
16
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
17
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '-'
18
+ ]
19
+
20
+ const keys = [
21
+ 'SPACE', 'HOME', 'END', 'INS', 'PLUS', 'MINUS',
22
+ 'RIGHT', 'LEFT', 'UP', 'DOWN', 'TAB', 'BACKSPACE', 'COMMA', 'PERIOD', 'PGUP', 'PGDOWN', '-',
23
+ 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10',
24
+ 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19',
25
+ 'F20', 'F21', 'F22', 'F23', 'F24',
26
+ ];
27
+
28
+
29
+ class KeyboardShortcutDialog extends BasicDialog {
30
+ private key = new Observable('')
31
+
32
+ constructor(private model: KeyboardShortcutModel) {
33
+ super('Keyboard Shortcut');
34
+ }
35
+
36
+ protected build(): void {
37
+ let add = this.add
38
+ let model = this.model
39
+ this.dialog.setAcceptButtonEnabled(false)
40
+ this.dialog.showHelpButton(false)
41
+ this.builder.context.layout.margin = 5
42
+ this.dialog.minWidth = 250
43
+
44
+ this.key.intercept((_, current) => {
45
+ let value = current
46
+ if (current.length > 1 && !contains(keys, current))
47
+ value = current[1]
48
+ if (value.length === 1)
49
+ value = value.toUpperCase()
50
+ return value
51
+ })
52
+ this.key.connect((text) => {
53
+ model.shortcut.value = this.getShortcut(text)
54
+ })
55
+
56
+ const metaKeys = [model.control, model.alt, model.shift, model.windows];
57
+ for (const observable of metaKeys) {
58
+ observable.connect(() => this.key.trigger());
59
+ }
60
+
61
+ this.key.connect((text) => {
62
+ this.dialog.setAcceptButtonEnabled(Boolean(text))
63
+ })
64
+
65
+ add.group('Assign Keyboard Shortcut').build((layout) => {
66
+ layout.spacing = 5
67
+ add.edit().text(model.actionLabel).readOnly(true)
68
+ add.comboEdit().focus().items([...letters, ...keys]).changed(this.key).edited(this.key)
69
+ add.checkbox('Control').value(model.control)
70
+ add.checkbox('Option / Alt').value(model.alt)
71
+ add.checkbox('Shift').value(model.shift)
72
+ add.checkbox('Command / Windows').value(model.windows)
73
+ add.group('Shortcut:').style({ flat: true }).build(() => {
74
+ add.edit().text(model.shortcut).readOnly(true)
75
+ })
76
+ })
77
+ }
78
+
79
+ getShortcut(key: string): string {
80
+ let keys: string[] = []
81
+
82
+ if (this.model.control.value) keys.push('CTRL')
83
+ if (this.model.alt.value) keys.push('ALT')
84
+ if (this.model.shift.value) keys.push('SHIFT')
85
+ if (this.model.windows.value) keys.push('WIN')
86
+
87
+ keys.push(key)
88
+
89
+ return keys.join('+')
90
+ }
91
+ }
92
+
93
+ export const setKeyboardShortcut = (actionLabel: string, actionName: string) => {
94
+ let model = new KeyboardShortcutModel()
95
+ model.actionLabel = actionLabel
96
+
97
+ let dialog = new KeyboardShortcutDialog(model)
98
+ let result = dialog.run()
99
+
100
+ if (!result || !model.shortcut) return
101
+
102
+ setActionShortcut(actionName, model.shortcut.value)
103
+ }
@@ -0,0 +1,48 @@
1
+ const path = require('path');
2
+ const glob = require('glob');
3
+ const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
4
+
5
+ module.exports = (env, argv) => {
6
+ const isFileSpecified = env && env.file;
7
+ const entryFiles = isFileSpecified
8
+ ? [`./src/${env.file}.dsa.ts`]
9
+ : glob.sync('./src/**/*.dsa.ts');
10
+
11
+ return {
12
+ mode: 'production',
13
+ optimization: {
14
+ usedExports: true,
15
+ },
16
+ entry: entryFiles.reduce((acc, filePath) => {
17
+ const entry = filePath.replace('.dsa.ts', '').replace('src/', ''); // Remove 'src/' from the path
18
+ acc[entry] = `./${filePath}`;
19
+ return acc;
20
+ }, {}),
21
+ module: {
22
+ rules: [
23
+ {
24
+ test: /\.ts$/,
25
+ use: ['babel-loader', 'ts-loader'],
26
+ exclude: /node_modules/,
27
+ },
28
+ ],
29
+ },
30
+ resolve: {
31
+ extensions: ['.tsx', '.ts', '.js'],
32
+ plugins: [new TsconfigPathsPlugin()],
33
+ },
34
+ output: {
35
+ filename: '[name].dsa',
36
+ path: path.resolve(__dirname, 'dist'),
37
+ environment: {
38
+ arrowFunction: false,
39
+ bigIntLiteral: false,
40
+ const: false,
41
+ destructuring: false,
42
+ dynamicImport: false,
43
+ forOf: true,
44
+ module: false,
45
+ },
46
+ },
47
+ };
48
+ };