@microtronics/studio-cli 0.61.0 → 0.62.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 +9 -3
- package/README.md +17 -0
- package/dist/main.js +54 -57
- package/dist/studio-cli.d.ts +1 -0
- package/out/api.js +137 -149
- package/out/studio-cli.d.ts +5297 -0
- package/package.json +4 -4
- package/out/DeviceProfiles.js +0 -436
- package/out/FS.js +0 -43
- package/out/crc.js +0 -93
- package/out/dde/coreDefinitions.js +0 -541
- package/out/dde/dde.js +0 -618
- package/out/dde/dynamic-dde.schema.json +0 -1061
- package/out/dde/fileGenerators/api.js +0 -688
- package/out/dde/fileGenerators/dlo.js +0 -1014
- package/out/dde/fileGenerators/dloLocalData.js +0 -387
- package/out/dde/fileGenerators/xml.js +0 -180
- package/out/dde/yamlDdePreCompiler.js +0 -889
- package/out/defaultFiles.js +0 -114
- package/out/dependencies.js +0 -578
- package/out/dfiles/dfiles.js +0 -205
- package/out/diagnostics.js +0 -10
- package/out/dlo/CustomWasmFS.js +0 -258
- package/out/dlo/compiler.js +0 -231
- package/out/dlo/dlo.js +0 -33
- package/out/dlo/dlocc.js +0 -3799
- package/out/dlo/fileSequencer.js +0 -40
- package/out/dlo/preCompiler.js +0 -442
- package/out/dotenv.js +0 -28
- package/out/globals.js +0 -402
- package/out/helper.js +0 -145
- package/out/log.js +0 -60
- package/out/manifest.js +0 -492
- package/out/myDatanetClient.js +0 -291
- package/out/package/apm.js +0 -294
- package/out/package/library.js +0 -165
- package/out/package/package.js +0 -518
- package/out/registryAPI.js +0 -326
- package/out/scriptRunner.js +0 -107
- package/out/typings/registry.js +0 -7
package/out/dde/dde.js
DELETED
|
@@ -1,618 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.DDE = exports.DDE_PATH = void 0;
|
|
30
|
-
const vscode_uri_1 = require("vscode-uri");
|
|
31
|
-
const dependencies_1 = require("../dependencies");
|
|
32
|
-
const manifest_1 = require("../manifest");
|
|
33
|
-
const ajv_1 = __importDefault(require("ajv"));
|
|
34
|
-
const ajv_formats_1 = __importDefault(require("ajv-formats"));
|
|
35
|
-
const dynamic_dde_schema_json_1 = __importDefault(require("./dynamic-dde.schema.json"));
|
|
36
|
-
const yaml_1 = require("yaml");
|
|
37
|
-
const yamlDdePreCompiler_1 = require("./yamlDdePreCompiler");
|
|
38
|
-
const xml_1 = require("./fileGenerators/xml");
|
|
39
|
-
const defaultFiles_1 = require("../defaultFiles");
|
|
40
|
-
const semver = __importStar(require("semver"));
|
|
41
|
-
const dlo_1 = require("./fileGenerators/dlo");
|
|
42
|
-
const globals_1 = require("../globals");
|
|
43
|
-
const api_1 = require("./fileGenerators/api");
|
|
44
|
-
const helper_1 = require("../helper");
|
|
45
|
-
const registryAPI_1 = require("../registryAPI");
|
|
46
|
-
var yamlRangeToLineInformation = helper_1.Helper.yamlRangeToLineInformation;
|
|
47
|
-
const dloLocalData_1 = require("./fileGenerators/dloLocalData");
|
|
48
|
-
exports.DDE_PATH = defaultFiles_1.DefaultFiles.filePaths.dde.path;
|
|
49
|
-
// create file cache.
|
|
50
|
-
// yaml & json
|
|
51
|
-
// ...
|
|
52
|
-
var DDE;
|
|
53
|
-
(function (DDE) {
|
|
54
|
-
var convertBlobToString = helper_1.Helper.convertBlobToString;
|
|
55
|
-
/**
|
|
56
|
-
* The json schema to validate the dde structure
|
|
57
|
-
*/
|
|
58
|
-
DDE.DDE_SCHEMA = dynamic_dde_schema_json_1.default;
|
|
59
|
-
async function readYamlFile(filePath, fs) {
|
|
60
|
-
const yamlBin = await fs.readFile(filePath);
|
|
61
|
-
return convertBlobToString(yamlBin);
|
|
62
|
-
}
|
|
63
|
-
DDE.readYamlFile = readYamlFile;
|
|
64
|
-
/**
|
|
65
|
-
* Validate all dde files if they are valid based on the json schema
|
|
66
|
-
* @param cwd
|
|
67
|
-
* @param fs
|
|
68
|
-
* @param fileName
|
|
69
|
-
* @param globalDefines
|
|
70
|
-
*/
|
|
71
|
-
async function validate(cwd, fs, fileName = defaultFiles_1.DefaultFiles.fileNames.mainDDE, globalDefines) {
|
|
72
|
-
const diagnostics = [];
|
|
73
|
-
const manifest = await manifest_1.Manifest.read(cwd, fs);
|
|
74
|
-
const allLibraryFiles = await getDependencies(cwd, fs, manifest);
|
|
75
|
-
// If global defines are provided, apply template substitution to library YAML
|
|
76
|
-
if (globalDefines) {
|
|
77
|
-
for (const libraryFile of allLibraryFiles) {
|
|
78
|
-
const { result, unresolvedKeys } = globals_1.Globals.replaceDefineTemplates(libraryFile.yaml, globalDefines);
|
|
79
|
-
libraryFile.yaml = result;
|
|
80
|
-
for (const key of unresolvedKeys) {
|
|
81
|
-
diagnostics.push({
|
|
82
|
-
file: libraryFile.path,
|
|
83
|
-
level: 'error',
|
|
84
|
-
message: `Unresolved define template: {{${key}}}`,
|
|
85
|
-
line: 0,
|
|
86
|
-
startCharacter: 0,
|
|
87
|
-
endCharacter: 0
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
for (const libraryFile of allLibraryFiles) {
|
|
93
|
-
diagnostics.push(...validateJsonSchema(libraryFile.path, libraryFile.yaml));
|
|
94
|
-
}
|
|
95
|
-
// read project dde
|
|
96
|
-
const mainDdePath = vscode_uri_1.Utils.joinPath(cwd, exports.DDE_PATH, fileName);
|
|
97
|
-
let mainDdeYaml = await readYamlFile(mainDdePath, fs);
|
|
98
|
-
// Apply template substitution to main DDE YAML
|
|
99
|
-
if (globalDefines) {
|
|
100
|
-
const { result, unresolvedKeys } = globals_1.Globals.replaceDefineTemplates(mainDdeYaml, globalDefines);
|
|
101
|
-
mainDdeYaml = result;
|
|
102
|
-
for (const key of unresolvedKeys) {
|
|
103
|
-
diagnostics.push({
|
|
104
|
-
file: mainDdePath,
|
|
105
|
-
level: 'error',
|
|
106
|
-
message: `Unresolved define template: {{${key}}}`,
|
|
107
|
-
line: 0,
|
|
108
|
-
startCharacter: 0,
|
|
109
|
-
endCharacter: 0
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
diagnostics.push(...validateJsonSchema(mainDdePath, mainDdeYaml));
|
|
114
|
-
return {
|
|
115
|
-
manifest,
|
|
116
|
-
libraryFiles: allLibraryFiles,
|
|
117
|
-
main: {
|
|
118
|
-
path: mainDdePath,
|
|
119
|
-
yaml: mainDdeYaml
|
|
120
|
-
},
|
|
121
|
-
diagnostics
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
DDE.validate = validate;
|
|
125
|
-
/**
|
|
126
|
-
* Run dde compiler in the given studio directory
|
|
127
|
-
* @param cwd
|
|
128
|
-
* @param fs
|
|
129
|
-
* @param logger
|
|
130
|
-
* @param fileName
|
|
131
|
-
*/
|
|
132
|
-
async function compileDDE(cwd, fs, logger, fileName = defaultFiles_1.DefaultFiles.fileNames.mainDDE) {
|
|
133
|
-
const manifest = await manifest_1.Manifest.read(cwd, fs);
|
|
134
|
-
// Read global defines and pass to validate for template substitution
|
|
135
|
-
const resolvedConfig = await globals_1.Globals.read(cwd, fs, logger);
|
|
136
|
-
const validated = await validate(cwd, fs, fileName, resolvedConfig.flat);
|
|
137
|
-
// If schema validation found errors, return early with validation diagnostics
|
|
138
|
-
const validationErrors = validated.diagnostics.filter(d => d.level === 'error');
|
|
139
|
-
if (validationErrors.length > 0) {
|
|
140
|
-
return { ddeJSON: null, diagnostics: validated.diagnostics };
|
|
141
|
-
}
|
|
142
|
-
const historyJson = await getHistoryJson(cwd, fs, logger);
|
|
143
|
-
const preCompiler = new yamlDdePreCompiler_1.YamlPreCompiler.PreCompiler(manifest, validated.libraryFiles, historyJson);
|
|
144
|
-
const libraryDiagnostics = preCompiler.parseLibraries();
|
|
145
|
-
const librariesHaveError = libraryDiagnostics.find(diagnostics => diagnostics.level === 'error');
|
|
146
|
-
if (librariesHaveError) {
|
|
147
|
-
return { ddeJSON: null, diagnostics: [...validated.diagnostics, ...libraryDiagnostics] };
|
|
148
|
-
}
|
|
149
|
-
const { ddeJSON, diagnostics } = preCompiler.parseMainDDE(validated.main.path, validated.main.yaml);
|
|
150
|
-
return { ddeJSON, diagnostics: [...validated.diagnostics, ...diagnostics] };
|
|
151
|
-
}
|
|
152
|
-
DDE.compileDDE = compileDDE;
|
|
153
|
-
const ajv = new ajv_1.default({
|
|
154
|
-
strict: false,
|
|
155
|
-
allErrors: true,
|
|
156
|
-
verbose: true
|
|
157
|
-
});
|
|
158
|
-
// @ts-ignore
|
|
159
|
-
(0, ajv_formats_1.default)(ajv);
|
|
160
|
-
const validateDynamicDde = ajv.compile(DDE.DDE_SCHEMA);
|
|
161
|
-
/**
|
|
162
|
-
* Validate a given dde file against the dynamic dde schema.
|
|
163
|
-
* Returns structured diagnostics with YAML source positions instead of throwing.
|
|
164
|
-
* @param ddeFilePath - URI of the YAML file being validated
|
|
165
|
-
* @param yaml - Raw YAML content to validate
|
|
166
|
-
* @returns Array of diagnostics for any YAML syntax or schema validation errors
|
|
167
|
-
*/
|
|
168
|
-
function validateJsonSchema(ddeFilePath, yaml) {
|
|
169
|
-
const lineCounter = new yaml_1.LineCounter();
|
|
170
|
-
const yamlDoc = (0, yaml_1.parseDocument)(yaml, { lineCounter, keepSourceTokens: true });
|
|
171
|
-
// Collect YAML syntax errors as diagnostics
|
|
172
|
-
const diagnostics = [];
|
|
173
|
-
for (const yamlError of yamlDoc.errors) {
|
|
174
|
-
const lineInfo = yamlError.pos
|
|
175
|
-
? yamlRangeToLineInformation(lineCounter, [yamlError.pos[0], yamlError.pos[1], yamlError.pos[1]])
|
|
176
|
-
: { line: 0, startCharacter: 0, endCharacter: 0 };
|
|
177
|
-
diagnostics.push({
|
|
178
|
-
file: ddeFilePath,
|
|
179
|
-
level: 'error',
|
|
180
|
-
message: yamlError.message,
|
|
181
|
-
...lineInfo
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
// If the YAML has syntax errors, skip schema validation
|
|
185
|
-
if (diagnostics.length > 0) {
|
|
186
|
-
return diagnostics;
|
|
187
|
-
}
|
|
188
|
-
const json = yamlDoc.toJSON();
|
|
189
|
-
const result = validateDynamicDde(json);
|
|
190
|
-
if (!result) {
|
|
191
|
-
const allErrors = validateDynamicDde.errors || [];
|
|
192
|
-
// Filter out redundant 'if' keyword errors (the 'then'/'else' errors are more informative)
|
|
193
|
-
const errors = allErrors.filter(e => e.keyword !== 'if');
|
|
194
|
-
// Map each unique error message to a diagnostic with YAML source position
|
|
195
|
-
const seenMessages = new Set();
|
|
196
|
-
for (const error of errors) {
|
|
197
|
-
const msg = formatValidationError(error);
|
|
198
|
-
if (seenMessages.has(msg)) {
|
|
199
|
-
continue;
|
|
200
|
-
}
|
|
201
|
-
seenMessages.add(msg);
|
|
202
|
-
const lineInfo = resolveYamlLineInfo(yamlDoc, lineCounter, error);
|
|
203
|
-
diagnostics.push({
|
|
204
|
-
file: ddeFilePath,
|
|
205
|
-
level: 'error',
|
|
206
|
-
message: msg,
|
|
207
|
-
...lineInfo
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
return diagnostics;
|
|
212
|
-
}
|
|
213
|
-
DDE.validateJsonSchema = validateJsonSchema;
|
|
214
|
-
/**
|
|
215
|
-
* Creates and returns a new precompiler instance
|
|
216
|
-
* @param manifest
|
|
217
|
-
* @param libraries
|
|
218
|
-
* @param ddeHistory
|
|
219
|
-
* @constructor
|
|
220
|
-
*/
|
|
221
|
-
DDE.PreCompiler = (manifest, libraries, ddeHistory) => {
|
|
222
|
-
return new yamlDdePreCompiler_1.YamlPreCompiler.PreCompiler(manifest, libraries, ddeHistory);
|
|
223
|
-
};
|
|
224
|
-
/**
|
|
225
|
-
* File Generators
|
|
226
|
-
*/
|
|
227
|
-
/**
|
|
228
|
-
* Generate the needed xml for the myDatanet application
|
|
229
|
-
* @param ddeJSON
|
|
230
|
-
*/
|
|
231
|
-
function generateMyDatanetXML(manifest, ddeJSON) {
|
|
232
|
-
return (0, xml_1.generateXMLFromMap)(manifest, ddeJSON);
|
|
233
|
-
}
|
|
234
|
-
DDE.generateMyDatanetXML = generateMyDatanetXML;
|
|
235
|
-
/**
|
|
236
|
-
* Generate the xml dde notation and write it to the correct dist directory
|
|
237
|
-
* @param cwd
|
|
238
|
-
* @param fs
|
|
239
|
-
* @param ddeJSON
|
|
240
|
-
*/
|
|
241
|
-
async function exportMyDatanetXML(cwd, fs, logger, ddeJSON) {
|
|
242
|
-
const manifest = await manifest_1.Manifest.read(cwd, fs);
|
|
243
|
-
const xml = (0, xml_1.generateXMLFromMap)(manifest, ddeJSON);
|
|
244
|
-
const distFile = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.dist.ddeXmlPath);
|
|
245
|
-
await fs.writeFile(distFile, xml);
|
|
246
|
-
logger.log('Generated', defaultFiles_1.DefaultFiles.filePaths.dist.ddeXmlPath);
|
|
247
|
-
}
|
|
248
|
-
DDE.exportMyDatanetXML = exportMyDatanetXML;
|
|
249
|
-
/**
|
|
250
|
-
* Fetches the DDE history JSON of a previous version of an app and saves it to a designated file path.
|
|
251
|
-
*
|
|
252
|
-
* The method removes any previously fetched version of the DDE JSON file and fetches the configuration
|
|
253
|
-
* of the previous stable version of the app from a remote registry. If a valid DDE file exists for the previous version, it is downloaded
|
|
254
|
-
* and stored at the specified location.
|
|
255
|
-
*
|
|
256
|
-
* @param {URI} cwd - The current working directory of the project.
|
|
257
|
-
* @param {LocalFS} fs - The local filesystem utility for performing file operations.
|
|
258
|
-
* @param {Log.Logger} logger - Logger instance for logging informational, warning, and error messages.
|
|
259
|
-
* @param {Globals.ENV} env - The environment configuration parameters.
|
|
260
|
-
* @param {string|null} apiToken - The API authentication token for accessing the registry. A null value will prevent fetching the DDE JSON file.
|
|
261
|
-
* @return {Promise<void>} Resolves with no value if the process completes successfully or returns early for validation or fetch failures.
|
|
262
|
-
*/
|
|
263
|
-
async function fetchPreviousHistoryJson(cwd, fs, logger, env, apiToken) {
|
|
264
|
-
// remove the previous fetched version beforehand.
|
|
265
|
-
const previousDDEPath = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dde.historyJson);
|
|
266
|
-
await fs.rm(previousDDEPath).catch(console.error);
|
|
267
|
-
const manifest = await manifest_1.Manifest.read(cwd, fs);
|
|
268
|
-
// only validate if the project is an app and has a registry id
|
|
269
|
-
if (!manifest_1.Manifest.isApp(manifest) || !manifest.registry?.id) {
|
|
270
|
-
return;
|
|
271
|
-
}
|
|
272
|
-
if (!apiToken) {
|
|
273
|
-
logger.warn('Could not fetch dde of previous version: No API token provided.');
|
|
274
|
-
return;
|
|
275
|
-
}
|
|
276
|
-
const currentVersion = semver.coerce(manifest.version);
|
|
277
|
-
try {
|
|
278
|
-
const appProfile = await registryAPI_1.Registry.getExistingApplication(apiToken, manifest.publisher, manifest.registry.id, env);
|
|
279
|
-
const appVersions = appProfile.versions;
|
|
280
|
-
// find the previous version
|
|
281
|
-
const previousVersion = appVersions.find(version => {
|
|
282
|
-
// the appProfile is fetched with semver header true, therefore is the version.version a valid semver string.
|
|
283
|
-
return !semver.prerelease(version.version) && semver.lte(version.version, currentVersion);
|
|
284
|
-
});
|
|
285
|
-
const versionFile = previousVersion?.files.find(file => file.name === 'dde.json');
|
|
286
|
-
if (!versionFile) {
|
|
287
|
-
// the version does not have a dde.json file
|
|
288
|
-
logger.warn('Could not find a valid previous released app version to fetch the previous dde from.');
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
const request = await fetch(versionFile.downloadUrl, {
|
|
292
|
-
headers: {
|
|
293
|
-
...(0, registryAPI_1.buildAuthHeader)(apiToken),
|
|
294
|
-
...registryAPI_1.Registry.injectSemverHeader(true)
|
|
295
|
-
}
|
|
296
|
-
});
|
|
297
|
-
if (request.status !== 200) {
|
|
298
|
-
// the version does not have a dde.json file
|
|
299
|
-
logger.warn(`Could not fetch the dde.json of version "${previousVersion?.version}"`);
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
const historyJson = await request.text();
|
|
303
|
-
await fs.writeFile(previousDDEPath, historyJson);
|
|
304
|
-
logger.log(`Saved history.json of previous app version ${previousVersion.version}`);
|
|
305
|
-
}
|
|
306
|
-
catch (e) {
|
|
307
|
-
logger.error('Failed to fetch the dde of previous version', e);
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
DDE.fetchPreviousHistoryJson = fetchPreviousHistoryJson;
|
|
311
|
-
/**
|
|
312
|
-
* Read the correct history.json file from the project
|
|
313
|
-
* @param cwd
|
|
314
|
-
* @param fs
|
|
315
|
-
* @param logger
|
|
316
|
-
*/
|
|
317
|
-
async function getHistoryJson(cwd, fs, logger) {
|
|
318
|
-
try {
|
|
319
|
-
const prevHistoryPath = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dde.historyJson);
|
|
320
|
-
if (await fs.stat(prevHistoryPath)) {
|
|
321
|
-
const binary = await fs.readFile(prevHistoryPath);
|
|
322
|
-
return JSON.parse(convertBlobToString(binary));
|
|
323
|
-
}
|
|
324
|
-
// fallback to previous history.json located within the projects dde directory
|
|
325
|
-
const historyPath = vscode_uri_1.Utils.joinPath(cwd, exports.DDE_PATH, 'history.json');
|
|
326
|
-
if (await fs.stat(historyPath)) {
|
|
327
|
-
logger.warn(`"${defaultFiles_1.DefaultFiles.filePaths.studio.auto.dde.historyJson}" does not exist - fallback to "${exports.DDE_PATH}history.json"`);
|
|
328
|
-
const binary = await fs.readFile(historyPath);
|
|
329
|
-
const historyJson = JSON.parse(convertBlobToString(binary));
|
|
330
|
-
const manifest = await manifest_1.Manifest.read(cwd, fs);
|
|
331
|
-
const currentSemver = semver.coerce(manifest.version)?.version;
|
|
332
|
-
// get previous dde version
|
|
333
|
-
const prev = Object.keys(historyJson || {})
|
|
334
|
-
.sort(semver.rcompare)
|
|
335
|
-
.find(version => version !== currentSemver);
|
|
336
|
-
if (!prev) {
|
|
337
|
-
return null;
|
|
338
|
-
}
|
|
339
|
-
const newHistoryFormat = historyJson[prev];
|
|
340
|
-
return { version: prev, ...newHistoryFormat };
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
catch (e) {
|
|
344
|
-
logger.error('Failed to read history.json', e);
|
|
345
|
-
}
|
|
346
|
-
logger.warn('history.json does not exist');
|
|
347
|
-
return null;
|
|
348
|
-
}
|
|
349
|
-
DDE.getHistoryJson = getHistoryJson;
|
|
350
|
-
/**
|
|
351
|
-
* Generate the object for the history.json
|
|
352
|
-
* @param ddeJson
|
|
353
|
-
* @param manifest
|
|
354
|
-
*/
|
|
355
|
-
function buildHistoryJson(ddeJson, manifest) {
|
|
356
|
-
const currentVersion = semver.coerce(manifest.version)?.version || '1.0.0';
|
|
357
|
-
return {
|
|
358
|
-
version: currentVersion,
|
|
359
|
-
...structuredClone(ddeJson)
|
|
360
|
-
};
|
|
361
|
-
}
|
|
362
|
-
DDE.buildHistoryJson = buildHistoryJson;
|
|
363
|
-
/**
|
|
364
|
-
* Generate the history.json file for the current version
|
|
365
|
-
* @param cwd
|
|
366
|
-
* @param fs
|
|
367
|
-
* @param logger
|
|
368
|
-
* @param ddeJSON
|
|
369
|
-
*/
|
|
370
|
-
async function exportHistoryJson(cwd, fs, logger, ddeJSON) {
|
|
371
|
-
const manifest = await manifest_1.Manifest.read(cwd, fs);
|
|
372
|
-
const newHistory = buildHistoryJson(ddeJSON, manifest);
|
|
373
|
-
const historyPath = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.dist.historyJson);
|
|
374
|
-
await fs.writeFile(historyPath, JSON.stringify(newHistory, null, '\t'));
|
|
375
|
-
logger.log('Generated', defaultFiles_1.DefaultFiles.filePaths.dist.historyJson);
|
|
376
|
-
}
|
|
377
|
-
DDE.exportHistoryJson = exportHistoryJson;
|
|
378
|
-
/**
|
|
379
|
-
* Clean up the .studio/auto/dlo directory
|
|
380
|
-
* @param cwd
|
|
381
|
-
* @param fs
|
|
382
|
-
* @internal
|
|
383
|
-
*/
|
|
384
|
-
async function clearAutoDloDir(cwd, fs) {
|
|
385
|
-
return fs.rm(vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.path));
|
|
386
|
-
}
|
|
387
|
-
DDE.clearAutoDloDir = clearAutoDloDir;
|
|
388
|
-
/**
|
|
389
|
-
* Generate all dde related dlo files
|
|
390
|
-
* @param cwd
|
|
391
|
-
* @param fs
|
|
392
|
-
* @param logger
|
|
393
|
-
* @param ddeJSON
|
|
394
|
-
*/
|
|
395
|
-
async function exportAutoDloFiles(cwd, fs, logger, ddeJSON) {
|
|
396
|
-
await clearAutoDloDir(cwd, fs);
|
|
397
|
-
const manifest = await manifest_1.Manifest.read(cwd, fs);
|
|
398
|
-
const dependencies = await getDependencies(cwd, fs, manifest);
|
|
399
|
-
const resolvedConfig = await globals_1.Globals.read(cwd, fs, logger);
|
|
400
|
-
const autoInc = (0, dlo_1.generateAutoIncFromMap)(ddeJSON, resolvedConfig, manifest);
|
|
401
|
-
const appAutoDDE = new dlo_1.AutoDDEGenerator(manifest, ddeJSON, null);
|
|
402
|
-
const appDDEInc = appAutoDDE.generate();
|
|
403
|
-
// generate AutoDDe Files for the libraries:
|
|
404
|
-
for (const dependency of dependencies) {
|
|
405
|
-
const libAutoDDE = new dlo_1.AutoDDEGenerator(manifest, ddeJSON, dependency.libraryName);
|
|
406
|
-
const { globals, helper } = libAutoDDE.generate();
|
|
407
|
-
const libraryInc = [...globals, ...helper].join('\r\n');
|
|
408
|
-
const autoIncName = defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.autoDdeInc.replace('X', dependency.libraryName);
|
|
409
|
-
const incPath = vscode_uri_1.Utils.joinPath(cwd, autoIncName);
|
|
410
|
-
if (libraryInc.length) {
|
|
411
|
-
logger.log(`Generated`, autoIncName);
|
|
412
|
-
await fs.writeFile(incPath, libraryInc);
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
const mainDDEInc = (0, dlo_1.generateMainDDEIncFromMap)(ddeJSON);
|
|
416
|
-
const autoUplink = (0, dlo_1.generateAutoUplinkIncFromMap)(ddeJSON, dependencies.map(dep => dep.libraryName));
|
|
417
|
-
const autoLocalData = (0, dloLocalData_1.generateDloLocalDataIncFromMap)(ddeJSON);
|
|
418
|
-
const autoIncPath = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.autoInc);
|
|
419
|
-
await fs.writeFile(autoIncPath, autoInc);
|
|
420
|
-
logger.log(`Generated`, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.autoInc);
|
|
421
|
-
const autoUplinkIncPath = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.autoUplinkInc);
|
|
422
|
-
await fs.writeFile(autoUplinkIncPath, autoUplink);
|
|
423
|
-
logger.log(`Generated`, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.autoUplinkInc);
|
|
424
|
-
const autoLocalDataIncPath = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.autoLocalDataInc);
|
|
425
|
-
await fs.writeFile(autoLocalDataIncPath, autoLocalData);
|
|
426
|
-
logger.log(`Generated`, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.autoLocalDataInc);
|
|
427
|
-
const autoDdeAppPath = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.autoDdeInc.replace('X', 'app'));
|
|
428
|
-
await fs.writeFile(autoDdeAppPath, [...appDDEInc.globals, ...appDDEInc.helper].join('\n'));
|
|
429
|
-
logger.log('Generated', defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.autoDdeInc.replace('X', 'app'));
|
|
430
|
-
const autoDdeMainPath = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.autoDdeInc.replace('X', 'main'));
|
|
431
|
-
await fs.writeFile(autoDdeMainPath, mainDDEInc);
|
|
432
|
-
logger.log('Generated', defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.autoDdeInc.replace('X', 'main'));
|
|
433
|
-
await exportDefaultInc(cwd, fs, logger);
|
|
434
|
-
}
|
|
435
|
-
DDE.exportAutoDloFiles = exportAutoDloFiles;
|
|
436
|
-
/**
|
|
437
|
-
* Generate all dde related openapi files
|
|
438
|
-
* @param cwd
|
|
439
|
-
* @param fs
|
|
440
|
-
* @param ddeMap
|
|
441
|
-
*/
|
|
442
|
-
async function exportOpenApi(cwd, fs, logger, ddeMap) {
|
|
443
|
-
const manifest = await manifest_1.Manifest.read(cwd, fs);
|
|
444
|
-
const isLibrary = manifest_1.Manifest.isLibrary(manifest);
|
|
445
|
-
// remove previous api description:
|
|
446
|
-
const previousOpenAPIFileName = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.dist.path, 'dde-api.yaml');
|
|
447
|
-
await fs.rm(previousOpenAPIFileName).catch(() => { });
|
|
448
|
-
const appPath = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.dist.ddeApi);
|
|
449
|
-
await fs.writeFile(appPath, (0, api_1.generateAPIFromMap)(ddeMap, manifest));
|
|
450
|
-
logger.log(`Generated`, defaultFiles_1.DefaultFiles.filePaths.dist.ddeApi);
|
|
451
|
-
// generate the api description for the library part of the project
|
|
452
|
-
if (isLibrary) {
|
|
453
|
-
const libPath = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.dist.ddeApiPath, `${manifest.name}.yaml`);
|
|
454
|
-
const content = (0, api_1.generateAPIFromMap)(ddeMap, manifest, manifest.name);
|
|
455
|
-
if (content.length) {
|
|
456
|
-
await fs.writeFile(libPath, content);
|
|
457
|
-
logger.log(`Generated`, defaultFiles_1.DefaultFiles.filePaths.dist.ddeApiPath + `${manifest.name}.yaml`);
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
DDE.exportOpenApi = exportOpenApi;
|
|
462
|
-
/**
|
|
463
|
-
* Generate and export the default.inc file
|
|
464
|
-
* @param cwd
|
|
465
|
-
* @param fs
|
|
466
|
-
* @internal
|
|
467
|
-
*/
|
|
468
|
-
async function exportDefaultInc(cwd, fs, logger) {
|
|
469
|
-
const defaultIncPaht = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.defaultInc);
|
|
470
|
-
const content = await (0, dlo_1.buildDefaultInc)(cwd, fs);
|
|
471
|
-
await fs.writeFile(defaultIncPaht, content);
|
|
472
|
-
logger.log('Generated', defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.defaultInc);
|
|
473
|
-
}
|
|
474
|
-
DDE.exportDefaultInc = exportDefaultInc;
|
|
475
|
-
})(DDE || (exports.DDE = DDE = {}));
|
|
476
|
-
/**
|
|
477
|
-
* Get dde files from any included library
|
|
478
|
-
* @param cwd
|
|
479
|
-
* @param fs
|
|
480
|
-
* @param manifest
|
|
481
|
-
*/
|
|
482
|
-
async function getDependencies(cwd, fs, manifest) {
|
|
483
|
-
const ddeFiles = [];
|
|
484
|
-
const allDependencies = await dependencies_1.Dependencies.getAll(manifest);
|
|
485
|
-
for (const dependencyId in allDependencies) {
|
|
486
|
-
const depPath = dependencies_1.Dependencies.dependencyToPath(cwd, dependencyId);
|
|
487
|
-
const name = dependencies_1.Dependencies.dependencyIdToName(dependencyId);
|
|
488
|
-
const ddePath = vscode_uri_1.Utils.joinPath(depPath, `${exports.DDE_PATH}/${name}.dde`);
|
|
489
|
-
const hasDDE = await fs.stat(ddePath);
|
|
490
|
-
if (hasDDE) {
|
|
491
|
-
ddeFiles.push({
|
|
492
|
-
libraryName: name,
|
|
493
|
-
path: ddePath,
|
|
494
|
-
yaml: await DDE.readYamlFile(ddePath, fs)
|
|
495
|
-
});
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
// push library projects dde file also into the list
|
|
499
|
-
if (manifest_1.Manifest.isLibrary(manifest)) {
|
|
500
|
-
const projectLibPath = vscode_uri_1.Utils.joinPath(cwd, `/${exports.DDE_PATH}/${manifest.name}.dde`);
|
|
501
|
-
if (await fs.stat(projectLibPath)) {
|
|
502
|
-
ddeFiles.push({
|
|
503
|
-
libraryName: manifest.name,
|
|
504
|
-
path: projectLibPath,
|
|
505
|
-
yaml: await DDE.readYamlFile(projectLibPath, fs)
|
|
506
|
-
});
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
return ddeFiles;
|
|
510
|
-
}
|
|
511
|
-
/**
|
|
512
|
-
* Extract a custom error message from the schema's errorMessage metadata.
|
|
513
|
-
* Supports both string and object formats (e.g. { required: { field: "msg" } }).
|
|
514
|
-
* @param schemaErrorMessage - The errorMessage property from the parent schema
|
|
515
|
-
* @param keyword - The ajv error keyword
|
|
516
|
-
* @param params - The ajv error params
|
|
517
|
-
*/
|
|
518
|
-
function extractCustomErrorMessage(schemaErrorMessage, keyword, params) {
|
|
519
|
-
if (typeof schemaErrorMessage === 'string') {
|
|
520
|
-
return schemaErrorMessage;
|
|
521
|
-
}
|
|
522
|
-
if (typeof schemaErrorMessage !== 'object' || schemaErrorMessage === null) {
|
|
523
|
-
return '';
|
|
524
|
-
}
|
|
525
|
-
const keywordMessages = schemaErrorMessage[keyword];
|
|
526
|
-
if (typeof keywordMessages === 'string') {
|
|
527
|
-
return keywordMessages;
|
|
528
|
-
}
|
|
529
|
-
if (typeof keywordMessages !== 'object' || keywordMessages === null) {
|
|
530
|
-
return '';
|
|
531
|
-
}
|
|
532
|
-
const paramKey = params?.missingProperty;
|
|
533
|
-
return paramKey ? (keywordMessages[paramKey] ?? '') : '';
|
|
534
|
-
}
|
|
535
|
-
/**
|
|
536
|
-
* Build a human-readable message for a specific ajv error keyword.
|
|
537
|
-
* @param keyword - The ajv error keyword
|
|
538
|
-
* @param params - The ajv error params
|
|
539
|
-
* @param message - The default ajv error message
|
|
540
|
-
* @param parentSchema - The parent schema object (available in verbose mode)
|
|
541
|
-
*/
|
|
542
|
-
function buildKeywordMessage(keyword, params, message, parentSchema) {
|
|
543
|
-
const keywordMessageMap = {
|
|
544
|
-
required: () => `Missing required property '${params.missingProperty}'.`,
|
|
545
|
-
additionalProperties: () => `Unknown property '${params.additionalProperty}' is not allowed.`,
|
|
546
|
-
type: () => `Must be of type '${params.type}'.`,
|
|
547
|
-
enum: () => `Must be one of the allowed values: ${JSON.stringify(params.allowedValues)}.`,
|
|
548
|
-
pattern: () => `Value does not match the required pattern. ${parentSchema?.patternErrorMessage ?? message}`,
|
|
549
|
-
minimum: () => `${message}.`,
|
|
550
|
-
maximum: () => `${message}.`,
|
|
551
|
-
exclusiveMinimum: () => `${message}.`,
|
|
552
|
-
exclusiveMaximum: () => `${message}.`,
|
|
553
|
-
not: () => `This value is not allowed here. ${parentSchema?.description ?? ''}`.trimEnd(),
|
|
554
|
-
anyOf: () => `Value does not match any of the allowed schemas. ${parentSchema?.description ?? ''}`.trimEnd(),
|
|
555
|
-
oneOf: () => `Value does not match any of the allowed schemas. ${parentSchema?.description ?? ''}`.trimEnd()
|
|
556
|
-
};
|
|
557
|
-
const formatter = keywordMessageMap[keyword];
|
|
558
|
-
return formatter ? formatter() : message;
|
|
559
|
-
}
|
|
560
|
-
/**
|
|
561
|
-
* Format a single ajv validation error into a human-readable string.
|
|
562
|
-
* Uses the schema's errorMessage/description metadata when available (verbose mode)
|
|
563
|
-
* to provide more meaningful messages than the default ajv output.
|
|
564
|
-
* @param error - The ajv error object (verbose mode includes parentSchema)
|
|
565
|
-
*/
|
|
566
|
-
function formatValidationError(error) {
|
|
567
|
-
const path = error.instancePath || '/';
|
|
568
|
-
const parentSchema = error.parentSchema;
|
|
569
|
-
const customMessage = extractCustomErrorMessage(parentSchema?.errorMessage, error.keyword, error.params);
|
|
570
|
-
if (customMessage) {
|
|
571
|
-
return `${path}: ${customMessage}`;
|
|
572
|
-
}
|
|
573
|
-
const message = error.message || 'unknown validation error';
|
|
574
|
-
return `${path}: ${buildKeywordMessage(error.keyword, error.params, message, parentSchema)}`;
|
|
575
|
-
}
|
|
576
|
-
/**
|
|
577
|
-
* Resolve the YAML AST node range for a given AJV error's instancePath.
|
|
578
|
-
* Walks the parsed YAML document tree using the JSON Pointer segments from the error.
|
|
579
|
-
* Falls back to parent nodes when the exact path cannot be resolved.
|
|
580
|
-
* @param yamlDoc - The parsed YAML document with source positions
|
|
581
|
-
* @param instancePath - AJV instancePath (JSON Pointer format, e.g. "/measurement/temperature/type")
|
|
582
|
-
* @returns The YAML source range [offset, offsetEnd, srcTokenEnd] or null if unresolvable
|
|
583
|
-
*/
|
|
584
|
-
function resolveYamlNodeRange(yamlDoc, instancePath) {
|
|
585
|
-
const segments = instancePath
|
|
586
|
-
.split('/')
|
|
587
|
-
.filter(Boolean)
|
|
588
|
-
.map(s => {
|
|
589
|
-
const num = Number(s);
|
|
590
|
-
return Number.isNaN(num) ? s : num;
|
|
591
|
-
});
|
|
592
|
-
// Try to find the exact node, falling back to parent nodes
|
|
593
|
-
for (let depth = segments.length; depth >= 0; depth--) {
|
|
594
|
-
const path = segments.slice(0, depth);
|
|
595
|
-
const node = yamlDoc.getIn(path, true);
|
|
596
|
-
if (node?.range) {
|
|
597
|
-
return node.range;
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
return null;
|
|
601
|
-
}
|
|
602
|
-
/**
|
|
603
|
-
* Resolve YAML source line information for an AJV validation error.
|
|
604
|
-
* Uses the error's instancePath to locate the corresponding YAML AST node
|
|
605
|
-
* and converts its range to line/character positions.
|
|
606
|
-
* @param yamlDoc - The parsed YAML document
|
|
607
|
-
* @param lineCounter - The YAML LineCounter used during parsing
|
|
608
|
-
* @param error - The AJV error object
|
|
609
|
-
* @returns Object with line, startCharacter, and endCharacter
|
|
610
|
-
*/
|
|
611
|
-
function resolveYamlLineInfo(yamlDoc, lineCounter, error) {
|
|
612
|
-
const nodeRange = resolveYamlNodeRange(yamlDoc, error.instancePath || '');
|
|
613
|
-
if (nodeRange) {
|
|
614
|
-
return yamlRangeToLineInformation(lineCounter, nodeRange);
|
|
615
|
-
}
|
|
616
|
-
return { line: 0, startCharacter: 0, endCharacter: 0 };
|
|
617
|
-
}
|
|
618
|
-
//# sourceMappingURL=dde.js.map
|