@microtronics/studio-cli 0.53.0 → 0.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -2
- package/dist/main.js +47 -45
- package/dist/studio-cli.d.ts +4 -1
- package/out/dde/dde.js +1 -1
- package/out/dde/fileGenerators/dlo.js +17 -1
- package/out/defaultFiles.js +2 -1
- package/out/globals.js +66 -17
- package/out/package/library.js +1 -1
- package/out/package/package.js +21 -2
- package/package.json +1 -1
package/dist/studio-cli.d.ts
CHANGED
|
@@ -1812,6 +1812,7 @@ export declare namespace DefaultFiles {
|
|
|
1812
1812
|
bloPath: string;
|
|
1813
1813
|
reportTemplate: string;
|
|
1814
1814
|
definesTs: string;
|
|
1815
|
+
definesAppTs: string;
|
|
1815
1816
|
};
|
|
1816
1817
|
dlo: {
|
|
1817
1818
|
path: string;
|
|
@@ -2252,6 +2253,8 @@ export declare namespace Globals {
|
|
|
2252
2253
|
definesWithSource: {
|
|
2253
2254
|
[key: string]: DefineEntry;
|
|
2254
2255
|
};
|
|
2256
|
+
/** For library projects: defaults-only config without app.ini overrides */
|
|
2257
|
+
defaultsOnly?: ResolvedConfig;
|
|
2255
2258
|
}
|
|
2256
2259
|
/**
|
|
2257
2260
|
* Read all ini files from the project directory and its dependencies.
|
|
@@ -2275,7 +2278,7 @@ export declare namespace Globals {
|
|
|
2275
2278
|
* @param fs - filesystem abstraction
|
|
2276
2279
|
* @param resolvedConfig - the resolved config from Globals.read()
|
|
2277
2280
|
*/
|
|
2278
|
-
export function exportDefinesTs(cwd: URI, fs: LocalFS, resolvedConfig: ResolvedConfig): Promise<void>;
|
|
2281
|
+
export function exportDefinesTs(cwd: URI, fs: LocalFS, resolvedConfig: ResolvedConfig, outputPath?: string): Promise<void>;
|
|
2279
2282
|
/**
|
|
2280
2283
|
* Replace {{KEY}} template tokens in a string with their resolved values.
|
|
2281
2284
|
*
|
package/out/dde/dde.js
CHANGED
|
@@ -396,7 +396,7 @@ var DDE;
|
|
|
396
396
|
const manifest = await manifest_1.Manifest.read(cwd, fs);
|
|
397
397
|
const dependencies = await getDependencies(cwd, fs, manifest);
|
|
398
398
|
const resolvedConfig = await globals_1.Globals.read(cwd, fs, logger);
|
|
399
|
-
const autoInc = (0, dlo_1.generateAutoIncFromMap)(ddeJSON, resolvedConfig
|
|
399
|
+
const autoInc = (0, dlo_1.generateAutoIncFromMap)(ddeJSON, resolvedConfig, manifest);
|
|
400
400
|
const appAutoDDE = new dlo_1.AutoDDEGenerator(manifest, ddeJSON, null);
|
|
401
401
|
const appDDEInc = appAutoDDE.generate();
|
|
402
402
|
// generate AutoDDe Files for the libraries:
|
|
@@ -97,7 +97,7 @@ function dloCoreSupportsFlags(manifest) {
|
|
|
97
97
|
return semver.gte(releaseVersion, '1.1.0');
|
|
98
98
|
}
|
|
99
99
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
100
|
-
function generateAutoIncFromMap(ddeMap,
|
|
100
|
+
function generateAutoIncFromMap(ddeMap, resolvedConfig, manifest) {
|
|
101
101
|
const _pwn = []; // sample code output for pawn
|
|
102
102
|
const pwn = _pwn.push.bind(_pwn);
|
|
103
103
|
function pwn_section(s) {
|
|
@@ -139,8 +139,24 @@ function generateAutoIncFromMap(ddeMap, globalDefines, manifest) {
|
|
|
139
139
|
/**
|
|
140
140
|
* generate global dlo defines if there are any
|
|
141
141
|
*/
|
|
142
|
+
const globalDefines = resolvedConfig.flat;
|
|
143
|
+
const { definesWithSource } = resolvedConfig;
|
|
142
144
|
pwn_section('GLOBAL DEFINES');
|
|
143
145
|
for (const [define, value] of Object.entries(globalDefines)) {
|
|
146
|
+
const comment = definesWithSource[define]?.comment;
|
|
147
|
+
if (comment) {
|
|
148
|
+
const lines = comment.split('\n');
|
|
149
|
+
if (lines.length === 1) {
|
|
150
|
+
pwn(`/** ${lines[0]} */`);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
pwn('/**');
|
|
154
|
+
for (const line of lines) {
|
|
155
|
+
pwn(` * ${line}`);
|
|
156
|
+
}
|
|
157
|
+
pwn(' */');
|
|
158
|
+
}
|
|
159
|
+
}
|
|
144
160
|
const valueIsDefine = Object.hasOwn(globalDefines, value);
|
|
145
161
|
addDefinition(define, `${value}`, valueIsDefine);
|
|
146
162
|
}
|
package/out/defaultFiles.js
CHANGED
|
@@ -73,7 +73,8 @@ var DefaultFiles;
|
|
|
73
73
|
dfilesProperties: `${deployDirectoryName}dfiles/properties.json`,
|
|
74
74
|
bloPath: `${deployDirectoryName}blo`,
|
|
75
75
|
reportTemplate: `${deployDirectoryName}/${DefaultFiles.fileNames.reportTemplate}`,
|
|
76
|
-
definesTs: `${deployDirectoryName}defines.ts
|
|
76
|
+
definesTs: `${deployDirectoryName}defines.ts`,
|
|
77
|
+
definesAppTs: `${deployDirectoryName}defines.app.ts`
|
|
77
78
|
},
|
|
78
79
|
dlo: {
|
|
79
80
|
path: dloDirectoryName,
|
package/out/globals.js
CHANGED
|
@@ -67,10 +67,10 @@ var Globals;
|
|
|
67
67
|
const depPath = dependencies_1.Dependencies.dependencyToPath(cwd, dependencyId);
|
|
68
68
|
const name = dependencies_1.Dependencies.dependencyIdToName(dependencyId);
|
|
69
69
|
const libIniPath = vscode_uri_1.Utils.joinPath(depPath, DLO_PATH, `${name}.ini`);
|
|
70
|
-
await mergeIniFile(fs, libIniPath, allDefines, sections, definesWithSource);
|
|
70
|
+
await mergeIniFile(fs, libIniPath, allDefines, sections, definesWithSource, name);
|
|
71
71
|
// defaults.ini files
|
|
72
72
|
const libDefaultsPath = vscode_uri_1.Utils.joinPath(depPath, defaultFiles_1.DefaultFiles.filePaths.defaultsIni);
|
|
73
|
-
await mergeIniFile(fs, libDefaultsPath, allDefines, sections, definesWithSource);
|
|
73
|
+
await mergeIniFile(fs, libDefaultsPath, allDefines, sections, definesWithSource, name);
|
|
74
74
|
}
|
|
75
75
|
// Load the library project's specific ini file (deprecated location)
|
|
76
76
|
if (manifest_1.Manifest.isLibrary(manifest)) {
|
|
@@ -78,7 +78,7 @@ var Globals;
|
|
|
78
78
|
if (logger && (await fs.stat(libIni))) {
|
|
79
79
|
logger.warn(`dlo/${manifest.name}.ini is deprecated. Please migrate your defines to defaults.ini in the project root.`);
|
|
80
80
|
}
|
|
81
|
-
await mergeIniFile(fs, libIni, allDefines, sections, definesWithSource);
|
|
81
|
+
await mergeIniFile(fs, libIni, allDefines, sections, definesWithSource, manifest.name);
|
|
82
82
|
}
|
|
83
83
|
// Load the project's main.ini and overwrite existing defines (deprecated location)
|
|
84
84
|
const mainIniRelPath = manifest.dlo?.iniFile || defaultFiles_1.DefaultFiles.filePaths.dlo.mainINI;
|
|
@@ -86,16 +86,19 @@ var Globals;
|
|
|
86
86
|
if (logger && (await fs.stat(mainIni))) {
|
|
87
87
|
logger.warn(`${mainIniRelPath} is deprecated. Please migrate your defines to app.ini in the project root.`);
|
|
88
88
|
}
|
|
89
|
-
|
|
89
|
+
const mainIniLabel = iniFileLabel(mainIniRelPath);
|
|
90
|
+
await mergeIniFile(fs, mainIni, allDefines, sections, definesWithSource, mainIniLabel);
|
|
90
91
|
// Project root: defaults.ini (library) or app.ini (app/addon/analytics)
|
|
91
92
|
if (manifest_1.Manifest.isLibrary(manifest)) {
|
|
92
93
|
const defaultsIni = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.defaultsIni);
|
|
93
|
-
await mergeIniFile(fs, defaultsIni, allDefines, sections, definesWithSource);
|
|
94
|
+
await mergeIniFile(fs, defaultsIni, allDefines, sections, definesWithSource, 'defaults');
|
|
94
95
|
}
|
|
95
|
-
// app.ini
|
|
96
|
+
// Snapshot defaults-only state before app.ini merge (for library dual-defines)
|
|
97
|
+
const defaultsOnly = snapshotDefaultsOnly(manifest, allDefines, sections, definesWithSource);
|
|
98
|
+
// app.ini is always loaded (provides local dev overrides for libraries, main config for apps)
|
|
96
99
|
const appIni = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.appIni);
|
|
97
|
-
await mergeIniFile(fs, appIni, allDefines, sections, definesWithSource);
|
|
98
|
-
return { flat: allDefines, sections, definesWithSource };
|
|
100
|
+
await mergeIniFile(fs, appIni, allDefines, sections, definesWithSource, 'app');
|
|
101
|
+
return { flat: allDefines, sections, definesWithSource, defaultsOnly };
|
|
99
102
|
}
|
|
100
103
|
Globals.read = read;
|
|
101
104
|
/**
|
|
@@ -106,7 +109,7 @@ var Globals;
|
|
|
106
109
|
* @param fs - filesystem abstraction
|
|
107
110
|
* @param resolvedConfig - the resolved config from Globals.read()
|
|
108
111
|
*/
|
|
109
|
-
async function exportDefinesTs(cwd, fs, resolvedConfig) {
|
|
112
|
+
async function exportDefinesTs(cwd, fs, resolvedConfig, outputPath) {
|
|
110
113
|
const entries = Object.entries(resolvedConfig.flat);
|
|
111
114
|
// Build the StudioDefines interface members
|
|
112
115
|
const interfaceLines = [];
|
|
@@ -149,7 +152,7 @@ var Globals;
|
|
|
149
152
|
lines.push('');
|
|
150
153
|
lines.push('export {};');
|
|
151
154
|
lines.push('');
|
|
152
|
-
const definesPath = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.dist.definesTs);
|
|
155
|
+
const definesPath = vscode_uri_1.Utils.joinPath(cwd, outputPath ?? defaultFiles_1.DefaultFiles.filePaths.dist.definesTs);
|
|
153
156
|
await fs.writeFile(definesPath, lines.join('\n'));
|
|
154
157
|
}
|
|
155
158
|
Globals.exportDefinesTs = exportDefinesTs;
|
|
@@ -174,6 +177,21 @@ var Globals;
|
|
|
174
177
|
}
|
|
175
178
|
Globals.replaceDefineTemplates = replaceDefineTemplates;
|
|
176
179
|
})(Globals || (exports.Globals = Globals = {}));
|
|
180
|
+
/**
|
|
181
|
+
* For library projects, snapshot the current defines state (before app.ini merge)
|
|
182
|
+
* so the published library only contains defaults.ini values.
|
|
183
|
+
* Returns undefined for non-library projects.
|
|
184
|
+
*/
|
|
185
|
+
function snapshotDefaultsOnly(manifest, allDefines, sections, definesWithSource) {
|
|
186
|
+
if (!manifest_1.Manifest.isLibrary(manifest)) {
|
|
187
|
+
return undefined;
|
|
188
|
+
}
|
|
189
|
+
return {
|
|
190
|
+
flat: { ...allDefines },
|
|
191
|
+
sections: structuredClone(sections),
|
|
192
|
+
definesWithSource: { ...definesWithSource }
|
|
193
|
+
};
|
|
194
|
+
}
|
|
177
195
|
/**
|
|
178
196
|
* Classify a trimmed ini-file line into one of the known kinds.
|
|
179
197
|
* Moves boolean-operator branching out of the main loop to reduce cognitive complexity.
|
|
@@ -252,10 +270,35 @@ function formatJsDoc(comment) {
|
|
|
252
270
|
function isNumericValue(value) {
|
|
253
271
|
return value !== '' && !isNaN(Number(value));
|
|
254
272
|
}
|
|
273
|
+
/**
|
|
274
|
+
* Derive a human-readable source label from an ini file path.
|
|
275
|
+
* Strips the directory prefix and `.ini` extension.
|
|
276
|
+
* E.g. `dlo/main.ini` → `main`, `app.ini` → `app`.
|
|
277
|
+
*/
|
|
278
|
+
function iniFileLabel(relPath) {
|
|
279
|
+
const filename = relPath.split('/').pop() || relPath;
|
|
280
|
+
return filename.replace(/\.ini$/i, '');
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Merge an incoming comment with an existing one.
|
|
284
|
+
*
|
|
285
|
+
* - Both present → join existing (already prefixed) and new (prefixed) with `\n`
|
|
286
|
+
* - Only existing → keep it
|
|
287
|
+
* - Only new → use it (prefixed)
|
|
288
|
+
* - Neither → undefined
|
|
289
|
+
*/
|
|
290
|
+
function mergeComment(existingComment, newRawComment, sourceLabel) {
|
|
291
|
+
const prefixedNew = newRawComment ? `${sourceLabel}: ${newRawComment}` : undefined;
|
|
292
|
+
if (existingComment && prefixedNew) {
|
|
293
|
+
return `${existingComment}\n${prefixedNew}`;
|
|
294
|
+
}
|
|
295
|
+
return prefixedNew || existingComment;
|
|
296
|
+
}
|
|
255
297
|
/**
|
|
256
298
|
* Create a DefineEntry, attaching a comment from the comment map if available.
|
|
299
|
+
* The comment is prefixed with the source label for provenance tracking.
|
|
257
300
|
*/
|
|
258
|
-
function createDefineEntry(stringValue, fileUri, lines, key, sectionName, commentMap) {
|
|
301
|
+
function createDefineEntry(stringValue, fileUri, lines, key, sectionName, commentMap, sourceLabel) {
|
|
259
302
|
const flatKey = sectionName ? `${sectionName}_${key}` : key;
|
|
260
303
|
const entry = {
|
|
261
304
|
value: stringValue,
|
|
@@ -263,23 +306,26 @@ function createDefineEntry(stringValue, fileUri, lines, key, sectionName, commen
|
|
|
263
306
|
sourceLine: findLineNumber(lines, key, sectionName)
|
|
264
307
|
};
|
|
265
308
|
if (commentMap[flatKey]) {
|
|
266
|
-
entry.comment = commentMap[flatKey]
|
|
309
|
+
entry.comment = `${sourceLabel}: ${commentMap[flatKey]}`;
|
|
267
310
|
}
|
|
268
311
|
return entry;
|
|
269
312
|
}
|
|
270
313
|
/**
|
|
271
314
|
* Merge all keys from a parsed ini section into the accumulators.
|
|
272
315
|
*/
|
|
273
|
-
function mergeSectionEntries(sectionName, sectionData, allDefines, sections, definesWithSource, fileUri, lines, commentMap) {
|
|
316
|
+
function mergeSectionEntries(sectionName, sectionData, allDefines, sections, definesWithSource, fileUri, lines, commentMap, sourceLabel) {
|
|
274
317
|
if (!sections[sectionName]) {
|
|
275
318
|
sections[sectionName] = {};
|
|
276
319
|
}
|
|
277
320
|
for (const [key, sectionValue] of Object.entries(sectionData)) {
|
|
278
321
|
const flatKey = `${sectionName}_${key}`;
|
|
322
|
+
const rawComment = commentMap[flatKey];
|
|
279
323
|
const stringValue = `${sectionValue}`;
|
|
280
324
|
allDefines[flatKey] = stringValue;
|
|
281
325
|
sections[sectionName][key] = stringValue;
|
|
282
|
-
|
|
326
|
+
const newEntry = createDefineEntry(stringValue, fileUri, lines, key, sectionName, commentMap, sourceLabel);
|
|
327
|
+
newEntry.comment = mergeComment(definesWithSource[flatKey]?.comment, rawComment, sourceLabel);
|
|
328
|
+
definesWithSource[flatKey] = newEntry;
|
|
283
329
|
}
|
|
284
330
|
}
|
|
285
331
|
/**
|
|
@@ -292,7 +338,7 @@ function mergeSectionEntries(sectionName, sectionData, allDefines, sections, def
|
|
|
292
338
|
* @param sections - accumulated sectioned config (mutated)
|
|
293
339
|
* @param definesWithSource - accumulated source tracking (mutated)
|
|
294
340
|
*/
|
|
295
|
-
async function mergeIniFile(fs, filePath, allDefines, sections, definesWithSource) {
|
|
341
|
+
async function mergeIniFile(fs, filePath, allDefines, sections, definesWithSource, sourceLabel) {
|
|
296
342
|
// early return if the file doesn't exist
|
|
297
343
|
if (!(await fs.stat(filePath))) {
|
|
298
344
|
return;
|
|
@@ -305,12 +351,15 @@ async function mergeIniFile(fs, filePath, allDefines, sections, definesWithSourc
|
|
|
305
351
|
const commentMap = extractComments(rawText);
|
|
306
352
|
for (const [sectionOrKey, value] of Object.entries(parsed)) {
|
|
307
353
|
if (typeof value === 'object' && value !== null) {
|
|
308
|
-
mergeSectionEntries(sectionOrKey, value, allDefines, sections, definesWithSource, fileUri, lines, commentMap);
|
|
354
|
+
mergeSectionEntries(sectionOrKey, value, allDefines, sections, definesWithSource, fileUri, lines, commentMap, sourceLabel);
|
|
309
355
|
}
|
|
310
356
|
else {
|
|
357
|
+
const rawComment = commentMap[sectionOrKey];
|
|
311
358
|
const stringValue = `${value}`;
|
|
312
359
|
allDefines[sectionOrKey] = stringValue;
|
|
313
|
-
|
|
360
|
+
const newEntry = createDefineEntry(stringValue, fileUri, lines, sectionOrKey, null, commentMap, sourceLabel);
|
|
361
|
+
newEntry.comment = mergeComment(definesWithSource[sectionOrKey]?.comment, rawComment, sourceLabel);
|
|
362
|
+
definesWithSource[sectionOrKey] = newEntry;
|
|
314
363
|
}
|
|
315
364
|
}
|
|
316
365
|
}
|
package/out/package/library.js
CHANGED
|
@@ -46,7 +46,7 @@ const defaultIgnore = [
|
|
|
46
46
|
'**/.vscode-test/**',
|
|
47
47
|
'**/.vscode-test-web/**'
|
|
48
48
|
];
|
|
49
|
-
defaultIgnore.push(...['**/.studio/**', '**/node_modules/**', STUDIO_IGNORE_FILE]);
|
|
49
|
+
defaultIgnore.push(...['**/.studio/**', '**/node_modules/**', STUDIO_IGNORE_FILE, 'dist/defines.app.ts']);
|
|
50
50
|
const MINIMATCH_OPTIONS = { dot: true };
|
|
51
51
|
var Library;
|
|
52
52
|
(function (Library) {
|
package/out/package/package.js
CHANGED
|
@@ -46,8 +46,7 @@ var Package;
|
|
|
46
46
|
// Generate dist/defines.ts before POV/BLO builds
|
|
47
47
|
try {
|
|
48
48
|
const resolvedConfig = await globals_1.Globals.read(cwd, fs, logger);
|
|
49
|
-
await
|
|
50
|
-
logger.log('Generated', defaultFiles_1.DefaultFiles.filePaths.dist.definesTs);
|
|
49
|
+
await exportDefinesForProject(cwd, fs, logger, resolvedConfig);
|
|
51
50
|
}
|
|
52
51
|
catch (e) {
|
|
53
52
|
logger.warn('Could not generate defines.ts:', e);
|
|
@@ -367,6 +366,26 @@ async function preBuild(cwd, fs, logger, env, apiToken, selectedParts) {
|
|
|
367
366
|
await dde_1.DDE.fetchPreviousHistoryJson(cwd, fs, logger, env, apiToken);
|
|
368
367
|
}
|
|
369
368
|
}
|
|
369
|
+
/**
|
|
370
|
+
* Export defines.ts file(s) based on project type.
|
|
371
|
+
* Library projects get two files: dist/defines.ts (defaults only) and dist/defines.app.ts (full merged).
|
|
372
|
+
* App/addon/analytics projects get a single dist/defines.ts with all merged values.
|
|
373
|
+
*/
|
|
374
|
+
async function exportDefinesForProject(cwd, fs, logger, resolvedConfig) {
|
|
375
|
+
if (resolvedConfig.defaultsOnly) {
|
|
376
|
+
// Library: dist/defines.ts = defaults only (for publishing)
|
|
377
|
+
await globals_1.Globals.exportDefinesTs(cwd, fs, resolvedConfig.defaultsOnly);
|
|
378
|
+
logger.log('Generated', defaultFiles_1.DefaultFiles.filePaths.dist.definesTs, '(defaults only)');
|
|
379
|
+
// Library: dist/defines.app.ts = full merged (for local dev)
|
|
380
|
+
await globals_1.Globals.exportDefinesTs(cwd, fs, resolvedConfig, defaultFiles_1.DefaultFiles.filePaths.dist.definesAppTs);
|
|
381
|
+
logger.log('Generated', defaultFiles_1.DefaultFiles.filePaths.dist.definesAppTs, '(with app.ini overrides)');
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
// App/addon/analytics: single merged file
|
|
385
|
+
await globals_1.Globals.exportDefinesTs(cwd, fs, resolvedConfig);
|
|
386
|
+
logger.log('Generated', defaultFiles_1.DefaultFiles.filePaths.dist.definesTs);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
370
389
|
/**
|
|
371
390
|
* Generates all needed files out of the dde declaration
|
|
372
391
|
* @param cwd
|