dazscript-framework 1.0.4 → 1.0.5

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 CHANGED
@@ -32,7 +32,7 @@ DAZ Script gives you direct access to the entire Daz Studio API. The DazScript F
32
32
  - **Fast UI development** — a fluent builder API lets you describe dialogs declaratively without touching the Qt widget API by hand.
33
33
  - **Two-way data binding** — link your data model to UI controls so they stay in sync automatically. The user types in a field and your model updates; you update the model in code and the UI reflects it instantly. No manual synchronization needed.
34
34
  - **One-command build** — `npm run build` compiles TypeScript to `.dsa` files that Daz Studio runs directly.
35
- - **Stable launcher shims** — built scripts use a two-level layout so iterating on your code never requires reinstalling actions in Daz Studio.
35
+ - **Stable launcher shims** — built scripts use a launcher/implementation layout so iterating on your code never requires reinstalling actions in Daz Studio.
36
36
  - **Automated installer generation** — `npm run installer` produces a full setup dialog by reading action metadata from your source code.
37
37
 
38
38
  ---
@@ -53,7 +53,7 @@ npm install dazscript-framework dazscript-types
53
53
  npx dazscript init
54
54
  ```
55
55
 
56
- Follow the prompt for your AppData author namespace (e.g. `YourName/my-project`). This creates `dazscript.config.ts`, `tsconfig.json`, and wires the `build`, `watch`, `icons`, and `installer` scripts into `package.json`.
56
+ Follow the prompt for your AppData author namespace (e.g. `YourName/my-project`). This creates `dazscript.config.ts`, `tsconfig.json`, and wires the `build`, `build:encrypted`, `watch`, `encrypt`, `icons`, and `installer` scripts into `package.json`.
57
57
 
58
58
  ### 3. Write the script
59
59
 
@@ -159,7 +159,7 @@ If `--app-data-path` is not provided, `init` prompts for the AppData author name
159
159
  This generates:
160
160
  - `dazscript.config.ts`
161
161
  - `tsconfig.json`
162
- - `package.json` script wiring for `build`, `watch`, `icons`, and `installer`
162
+ - `package.json` script wiring for `build`, `build:encrypted`, `watch`, `encrypt`, `icons`, and `installer`
163
163
 
164
164
  Available `init` flags:
165
165
 
@@ -244,7 +244,7 @@ action({ text: 'My Script' }, MyScript);
244
244
  Each built action produces two files:
245
245
 
246
246
  - `out/<script>.dsa` — the stable **launcher** registered with Daz Studio (menus, toolbars, shortcuts)
247
- - `out/<folder>/lib/<script-name>/script.dsa` — the **implementation bundle** the launcher executes
247
+ - `out/<folder>/lib/<script-name>/<script-name>.dsa` — the **implementation bundle** the launcher executes
248
248
 
249
249
  When you rebuild, only the implementation bundle changes. The launcher path stays stable, so re-registering the action in Daz Studio is normally not required.
250
250
 
@@ -256,7 +256,9 @@ To encrypt implementation bundles before packaging, run the build and then call
256
256
  npx dazscript encrypt --out-dir ./out --daz-studio "C:/Program Files/DAZ 3D/DAZStudio4/DAZStudio.exe"
257
257
  ```
258
258
 
259
- The `encrypt` command launches Daz Studio with `-headless -noPrompt`, converts each `out/**/lib/**/script.dsa` to `script.dse`, and deletes the source `script.dsa` after the matching encrypted file is written. Add `--keep-source` to leave the plain implementation bundles in place.
259
+ The `encrypt` command launches Daz Studio with `-headless -noPrompt`, converts each implementation bundle under `out/**/lib/**/*.dsa` to a matching `.dse` file, and deletes the source `.dsa` after the matching encrypted file is written. Add `--keep-source` to leave the plain implementation bundles in place.
260
+
261
+ Individual script packages can wrap this command in `package.json` scripts such as `npm run encrypt` or `npm run build:encrypted` so release packaging does not depend on remembering the full Daz Studio executable argument.
260
262
 
261
263
  ---
262
264
 
@@ -27,8 +27,7 @@ function findImplementationScripts(dir) {
27
27
 
28
28
  if (
29
29
  entry.isFile() &&
30
- entry.name === 'script.dsa' &&
31
- path.basename(path.dirname(entryPath)) !== 'lib' &&
30
+ entry.name.endsWith('.dsa') &&
32
31
  entryPath.split(path.sep).includes('lib')
33
32
  ) {
34
33
  scripts.push(entryPath);
@@ -93,8 +93,10 @@ function updatePackageJson(workdir, options) {
93
93
  ...(packageJson.scripts || {}),
94
94
  prebuild: 'npm run installer',
95
95
  build: 'dazscript build',
96
+ 'build:encrypted': 'npm run build && npm run encrypt',
96
97
  postbuild: 'npm run icons',
97
98
  watch: 'dazscript watch',
99
+ encrypt: 'dazscript encrypt --out-dir ./out --daz-studio "C:\\Program Files\\DAZ 3D\\DAZStudio4\\DAZStudio.exe"',
98
100
  icons: 'dazscript icons',
99
101
  installer: 'dazscript installer',
100
102
  };
@@ -23,6 +23,26 @@ function getImplementationRelativePath(outputRelativePath, extension = 'dsa') {
23
23
  ? path.posix.join('lib', outputBaseName)
24
24
  : path.posix.join(outputDirectory, 'lib', outputBaseName);
25
25
 
26
+ return path.posix.join(implementationDirectory, `${outputBaseName}.${extension}`);
27
+ }
28
+
29
+ function getFlatImplementationRelativePath(outputRelativePath, extension = 'dsa') {
30
+ const outputDirectory = path.posix.dirname(outputRelativePath);
31
+ const outputBaseName = path.posix.basename(outputRelativePath, '.dsa');
32
+ const implementationDirectory = outputDirectory === '.'
33
+ ? 'lib'
34
+ : path.posix.join(outputDirectory, 'lib');
35
+
36
+ return path.posix.join(implementationDirectory, `${outputBaseName}.${extension}`);
37
+ }
38
+
39
+ function getLegacyImplementationRelativePath(outputRelativePath, extension = 'dsa') {
40
+ const outputDirectory = path.posix.dirname(outputRelativePath);
41
+ const outputBaseName = path.posix.basename(outputRelativePath, '.dsa');
42
+ const implementationDirectory = outputDirectory === '.'
43
+ ? path.posix.join('lib', outputBaseName)
44
+ : path.posix.join(outputDirectory, 'lib', outputBaseName);
45
+
26
46
  return path.posix.join(implementationDirectory, `script.${extension}`);
27
47
  }
28
48
 
@@ -89,6 +109,14 @@ function ensureParentDir(filePath) {
89
109
  fs.mkdirSync(path.dirname(filePath), { recursive: true });
90
110
  }
91
111
 
112
+ function removeEmptyDir(dirPath) {
113
+ try {
114
+ fs.rmdirSync(dirPath);
115
+ } catch (_err) {
116
+ // Directory is missing or still contains user/generated files.
117
+ }
118
+ }
119
+
92
120
  function createActionLaunchers(workdir, options) {
93
121
  const outDir = path.resolve(workdir, options.outDir || './out');
94
122
  const appDataPath = validateAppDataPath(options.appDataPath, workdir);
@@ -105,11 +133,34 @@ function createActionLaunchers(workdir, options) {
105
133
  outDir,
106
134
  getImplementationRelativePath(outputRelativePath, 'dse')
107
135
  );
136
+ const legacyImplementationPath = path.join(
137
+ outDir,
138
+ getLegacyImplementationRelativePath(outputRelativePath)
139
+ );
140
+ const legacyEncryptedImplementationPath = path.join(
141
+ outDir,
142
+ getLegacyImplementationRelativePath(outputRelativePath, 'dse')
143
+ );
144
+ const flatImplementationPath = path.join(
145
+ outDir,
146
+ getFlatImplementationRelativePath(outputRelativePath)
147
+ );
148
+ const flatEncryptedImplementationPath = path.join(
149
+ outDir,
150
+ getFlatImplementationRelativePath(outputRelativePath, 'dse')
151
+ );
108
152
 
109
153
  if (!fs.existsSync(launcherPath)) {
110
154
  return;
111
155
  }
112
156
 
157
+ if (path.resolve(launcherPath) === path.resolve(implementationPath)) {
158
+ throw new Error(
159
+ `[dazscript] Launcher path collides with implementation path: ${implementationRelativePath}. ` +
160
+ `Move the source action out of a lib/ folder or use a different script name.`
161
+ );
162
+ }
163
+
113
164
  ensureParentDir(implementationPath);
114
165
  if (fs.existsSync(implementationPath)) {
115
166
  fs.unlinkSync(implementationPath);
@@ -117,6 +168,21 @@ function createActionLaunchers(workdir, options) {
117
168
  if (fs.existsSync(encryptedImplementationPath)) {
118
169
  fs.unlinkSync(encryptedImplementationPath);
119
170
  }
171
+ if (fs.existsSync(legacyImplementationPath)) {
172
+ fs.unlinkSync(legacyImplementationPath);
173
+ }
174
+ if (fs.existsSync(legacyEncryptedImplementationPath)) {
175
+ fs.unlinkSync(legacyEncryptedImplementationPath);
176
+ }
177
+ if (fs.existsSync(flatImplementationPath)) {
178
+ fs.unlinkSync(flatImplementationPath);
179
+ }
180
+ if (fs.existsSync(flatEncryptedImplementationPath)) {
181
+ fs.unlinkSync(flatEncryptedImplementationPath);
182
+ }
183
+ if (path.resolve(path.dirname(legacyImplementationPath)) !== path.resolve(path.dirname(implementationPath))) {
184
+ removeEmptyDir(path.dirname(legacyImplementationPath));
185
+ }
120
186
 
121
187
  fs.renameSync(launcherPath, implementationPath);
122
188
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dazscript-framework",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "author": "Freddy Diaz",
5
5
  "license": "MPL-2.0",
6
6
  "description": "",