@microtronics/studio-cli 0.18.0 → 0.19.1
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 +24 -0
- package/dist/studio-cli.d.ts +56 -34
- package/out/dde/fileGenerators/api.js +30 -8
- package/out/dde/fileGenerators/dlo.js +3 -0
- package/out/main.js +3 -0
- package/out/manifest.js +78 -5
- package/out/package/apm.js +37 -26
- package/out/package/package.js +10 -2
- package/package.json +1 -1
- package/studio-cli-addon +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
+
## 0.19.1 (2025-02-20)
|
|
4
|
+
|
|
5
|
+
# Changelog
|
|
6
|
+
|
|
7
|
+
## 0.19.0 (2025-02-19)
|
|
8
|
+
|
|
9
|
+
* test(studio-cli): tag header should not have property type ([5082db8](https://bitbucket.org/microtronics-core/vscode-studio/commits/5082db8))
|
|
10
|
+
* test(studio-cli): test if type addon can only used from specific version onwards ([213bc7c](https://bitbucket.org/microtronics-core/vscode-studio/commits/213bc7c))
|
|
11
|
+
* test(studio-cli): validate apm tag header creation ([e74acc8](https://bitbucket.org/microtronics-core/vscode-studio/commits/e74acc8))
|
|
12
|
+
* test(studio-cli): validate openapi generation for addons ([08176bc](https://bitbucket.org/microtronics-core/vscode-studio/commits/08176bc))
|
|
13
|
+
* feat(studio-cli): added function to validate if app id is an uuid ([60bda6f](https://bitbucket.org/microtronics-core/vscode-studio/commits/60bda6f))
|
|
14
|
+
* feat(studio-cli): allow creating an apm tag for addons ([a7d32c4](https://bitbucket.org/microtronics-core/vscode-studio/commits/a7d32c4))
|
|
15
|
+
* feat(studio-cli): generate api routes for addons ([a075407](https://bitbucket.org/microtronics-core/vscode-studio/commits/a075407))
|
|
16
|
+
* feat(studio-cli): improved manifest validation if type is addon ([c3ae0c9](https://bitbucket.org/microtronics-core/vscode-studio/commits/c3ae0c9))
|
|
17
|
+
* feat(studio-cli): only allow project type addon for a specific backend version ([46f0f28](https://bitbucket.org/microtronics-core/vscode-studio/commits/46f0f28))
|
|
18
|
+
* feat(studio-cli): support for new app type `apm` ([8041db3](https://bitbucket.org/microtronics-core/vscode-studio/commits/8041db3))
|
|
19
|
+
* chore(studio-cli): add run file for local addon development ([465a1f0](https://bitbucket.org/microtronics-core/vscode-studio/commits/465a1f0))
|
|
20
|
+
* chore(studio-cli): disable dlo per default if project type is addon ([a7f98af](https://bitbucket.org/microtronics-core/vscode-studio/commits/a7f98af))
|
|
21
|
+
* chore(studio-cli): dissallow setting hw/fw & productId if project type is addon ([74c90c3](https://bitbucket.org/microtronics-core/vscode-studio/commits/74c90c3))
|
|
22
|
+
* chore(studio-cli): improve type to allow `Manifest.ProjectTypes` ([fe6535f](https://bitbucket.org/microtronics-core/vscode-studio/commits/fe6535f))
|
|
23
|
+
* chore(studio-cli): validate for device profile id if dlo is enabled ([908fc9a](https://bitbucket.org/microtronics-core/vscode-studio/commits/908fc9a))
|
|
24
|
+
* revert(studio-cli): remove type property from tagheader object ([65f90ad](https://bitbucket.org/microtronics-core/vscode-studio/commits/65f90ad))
|
|
25
|
+
* refactor(studio-cli): added function to create the `baseTagHeader` ([ac9f83f](https://bitbucket.org/microtronics-core/vscode-studio/commits/ac9f83f))
|
|
26
|
+
|
|
3
27
|
## 0.18.0 (2025-02-13)
|
|
4
28
|
|
|
5
29
|
|
package/dist/studio-cli.d.ts
CHANGED
|
@@ -23,37 +23,14 @@ export declare namespace APM {
|
|
|
23
23
|
blo = "blo",
|
|
24
24
|
dfiles = "dfiles"
|
|
25
25
|
}
|
|
26
|
-
export interface TagHeader extends
|
|
27
|
-
|
|
28
|
-
version: string;
|
|
29
|
-
blo_level?: Manifest.BloAccessLevel;
|
|
30
|
-
required_be?: string;
|
|
31
|
-
required_hwfw?: string;
|
|
32
|
-
required_productcode?: string;
|
|
26
|
+
export interface TagHeader extends BaseTagHeader {
|
|
27
|
+
phase: TagPhase;
|
|
28
|
+
version: string | number;
|
|
33
29
|
}
|
|
34
|
-
export interface DevTagHeader {
|
|
35
|
-
name: string;
|
|
36
|
-
abstract: string;
|
|
37
|
-
author: string;
|
|
38
|
-
pip_id: string;
|
|
39
|
-
pov_location: Manifest.PovLocation;
|
|
40
|
-
pov_details_lowlevel: boolean;
|
|
41
|
-
blo_level: Manifest.BloAccessLevel;
|
|
30
|
+
export interface DevTagHeader extends BaseTagHeader {
|
|
42
31
|
blo_autostart: boolean;
|
|
43
|
-
/**
|
|
44
|
-
* ONE specific
|
|
45
|
-
* the version 0 for ONE
|
|
46
|
-
*/
|
|
47
|
-
version?: number;
|
|
48
|
-
/**
|
|
49
|
-
* ONE specific
|
|
50
|
-
* owner_id is the organizationID
|
|
51
|
-
*/
|
|
52
|
-
owner_id?: string;
|
|
53
|
-
required_be?: string;
|
|
54
|
-
required_hwfw?: string;
|
|
55
|
-
required_productcode?: string;
|
|
56
32
|
}
|
|
33
|
+
export function createBaseTagHeader(manifest: Manifest.Manifest): BaseTagHeader;
|
|
57
34
|
/**
|
|
58
35
|
* Create new release tag
|
|
59
36
|
* @param cwd
|
|
@@ -117,7 +94,26 @@ export declare namespace APM {
|
|
|
117
94
|
}>;
|
|
118
95
|
}
|
|
119
96
|
|
|
120
|
-
declare
|
|
97
|
+
declare interface BaseTagHeader {
|
|
98
|
+
name: string;
|
|
99
|
+
abstract: string;
|
|
100
|
+
author: string;
|
|
101
|
+
blo_level?: Manifest.BloAccessLevel;
|
|
102
|
+
required_be?: string;
|
|
103
|
+
required_hwfw?: string;
|
|
104
|
+
required_productcode?: string;
|
|
105
|
+
pov_location: Manifest.PovLocation;
|
|
106
|
+
pov_details_lowlevel: boolean;
|
|
107
|
+
pip_id: '';
|
|
108
|
+
/**
|
|
109
|
+
* exists only when app type is addon
|
|
110
|
+
*/
|
|
111
|
+
addon_max_per_site?: number;
|
|
112
|
+
/**
|
|
113
|
+
* exists only when app type is addon
|
|
114
|
+
*/
|
|
115
|
+
addon_max_sources?: number;
|
|
116
|
+
}
|
|
121
117
|
|
|
122
118
|
declare interface components {
|
|
123
119
|
schemas: {
|
|
@@ -173,6 +169,7 @@ declare interface components {
|
|
|
173
169
|
NewApplication: {
|
|
174
170
|
/** @description The project name */
|
|
175
171
|
name: string;
|
|
172
|
+
type?: components["schemas"]["ApplicationType"];
|
|
176
173
|
/** @description Short description what this library does */
|
|
177
174
|
description: string;
|
|
178
175
|
targetSystem: components["schemas"]["TargetSystem"];
|
|
@@ -180,7 +177,11 @@ declare interface components {
|
|
|
180
177
|
organizationId?: string;
|
|
181
178
|
/** @description Defines which servers are allowed to see this application. If null, the application wont be shared with anyone */
|
|
182
179
|
allowedBackends?: ("*" | string[]) | null;
|
|
180
|
+
/** @description Sites with the given APM ID are allowed to be defined as addon parent. This property is only available if the project type is 'addon' */
|
|
181
|
+
allowedApplications?: ("*" | string[]) | null;
|
|
183
182
|
};
|
|
183
|
+
/** @enum {string} */
|
|
184
|
+
ApplicationType: "app" | "addon";
|
|
184
185
|
ApplicationInformationBase: {
|
|
185
186
|
version: components["parameters"]["ApplicationVersion"];
|
|
186
187
|
publisherId: components["parameters"]["PublisherId"];
|
|
@@ -2045,13 +2046,21 @@ export declare namespace Manifest {
|
|
|
2045
2046
|
* The source filename where the information is stored in
|
|
2046
2047
|
*/
|
|
2047
2048
|
const fileName = "studio.json";
|
|
2048
|
-
export
|
|
2049
|
+
export enum DeviceProfiles {
|
|
2050
|
+
m22x = "m22x",
|
|
2051
|
+
m23x = "m23x",
|
|
2052
|
+
nrf91 = "nrf91",
|
|
2053
|
+
m2blegw = "m2blegw",
|
|
2054
|
+
m2easyv3 = "m2easyv3",
|
|
2055
|
+
m2easyiot = "m2easyiot"
|
|
2056
|
+
}
|
|
2049
2057
|
/**
|
|
2050
2058
|
* Type of the iot app project
|
|
2051
2059
|
*/
|
|
2052
2060
|
export enum ProjectTypes {
|
|
2053
2061
|
app = "app",
|
|
2054
|
-
library = "library"
|
|
2062
|
+
library = "library",
|
|
2063
|
+
addon = "addon"
|
|
2055
2064
|
}
|
|
2056
2065
|
export interface Manifest {
|
|
2057
2066
|
version: string;
|
|
@@ -2061,7 +2070,7 @@ export declare namespace Manifest {
|
|
|
2061
2070
|
type: ProjectTypes;
|
|
2062
2071
|
legacyProject?: boolean;
|
|
2063
2072
|
icon?: string;
|
|
2064
|
-
dpid
|
|
2073
|
+
dpid?: DeviceProfiles;
|
|
2065
2074
|
engines?: {
|
|
2066
2075
|
backend?: string;
|
|
2067
2076
|
hwfw?: string[];
|
|
@@ -2118,7 +2127,7 @@ export declare namespace Manifest {
|
|
|
2118
2127
|
*/
|
|
2119
2128
|
export function read(cwd: URI, fs: LocalFS): Promise<Manifest>;
|
|
2120
2129
|
/**
|
|
2121
|
-
* Reads the studio.json as an
|
|
2130
|
+
* Reads the studio.json as an Uint8Array
|
|
2122
2131
|
* @param cwd
|
|
2123
2132
|
* @param fs
|
|
2124
2133
|
*/
|
|
@@ -2134,6 +2143,16 @@ export declare namespace Manifest {
|
|
|
2134
2143
|
* Check if the current project is a library project
|
|
2135
2144
|
*/
|
|
2136
2145
|
export function isLibrary(manifest: Manifest.Manifest): boolean;
|
|
2146
|
+
/**
|
|
2147
|
+
* Check if the current project is an addon project
|
|
2148
|
+
* @param manifest
|
|
2149
|
+
*/
|
|
2150
|
+
export function isAddon(manifest: Manifest.Manifest): boolean;
|
|
2151
|
+
/**
|
|
2152
|
+
* Check if the current project is an app project
|
|
2153
|
+
* @param manifest
|
|
2154
|
+
*/
|
|
2155
|
+
export function isApp(manifest: Manifest.Manifest): boolean;
|
|
2137
2156
|
/**
|
|
2138
2157
|
* Validates if the properties within
|
|
2139
2158
|
* @param cwd
|
|
@@ -2148,6 +2167,7 @@ export declare namespace Manifest {
|
|
|
2148
2167
|
export function validatePublisherId(publisher: string): "No publisher set yet" | "Publisher can only contain 'A' through 'Z', 'a' through 'z', '0' through '9' and '-'. The Publisher start with an alphabetic or numeric character." | null;
|
|
2149
2168
|
export function validatePublisherOnline(token: Registry.AuthToken, publisher: string): Promise<string | null>;
|
|
2150
2169
|
export function validateRegistryAllowedBackends(allowedBackends: undefined | null | string | string[]): Promise<string | null>;
|
|
2170
|
+
export function validateRegistryAllowedApplications(allowedApplications: undefined | null | string | string[]): Promise<string | null>;
|
|
2151
2171
|
export function validateApplicationIcon(cwd: URI, fs: LocalFS, manifest: Manifest.Manifest): Promise<void>;
|
|
2152
2172
|
export function validateEngineSettings(manifest: Manifest.Manifest): void;
|
|
2153
2173
|
/**
|
|
@@ -4289,7 +4309,9 @@ export declare namespace Registry {
|
|
|
4289
4309
|
export function fetchCustomContent(token: AuthToken, contentURL: string, json?: boolean, env?: Globals.ENV): Promise<ArrayBuffer | any>;
|
|
4290
4310
|
export type Publisher = components['schemas']['Publisher'];
|
|
4291
4311
|
export function getPublisher(token: AuthToken, publisherId: string): Promise<Publisher | null>;
|
|
4292
|
-
export type ApiNewApplication = components['schemas']['NewApplication']
|
|
4312
|
+
export type ApiNewApplication = components['schemas']['NewApplication'] & {
|
|
4313
|
+
type?: string | Manifest.ProjectTypes;
|
|
4314
|
+
};
|
|
4293
4315
|
export function createNewApplication(token: AuthToken, publisherId: string, newApplication: ApiNewApplication, env?: Globals.ENV): Promise<string | null | undefined>;
|
|
4294
4316
|
export type ApplicationDetailInformation = components['schemas']['ApplicationDetailInformation'];
|
|
4295
4317
|
export function getExistingApplication(token: AuthToken, publisherId: string, applicationId: string, env?: Globals.ENV): Promise<ApplicationDetailInformation>;
|
|
@@ -30,7 +30,9 @@ const coreDefinitions_1 = require("../coreDefinitions");
|
|
|
30
30
|
var ContainerType = coreDefinitions_1.DDE_Core.ContainerType;
|
|
31
31
|
var TransferDirection = coreDefinitions_1.DDE_Core.TransferDirection;
|
|
32
32
|
var fieldTypeDefinitions = coreDefinitions_1.DDE_Core.fieldTypeDefinitions;
|
|
33
|
+
const manifest_1 = require("../../manifest");
|
|
33
34
|
const contextIdRef = { $ref: '#/components/parameters/contextId' };
|
|
35
|
+
const addonIdRef = { $ref: '#/components/parameters/addonId' };
|
|
34
36
|
const histdataResponseRef = { $ref: '#/components/schemas/histdataResponse' };
|
|
35
37
|
const histdataRequestRef = { $ref: '#/components/schemas/histdataRequest' };
|
|
36
38
|
const rapidM2MStampRef = { $ref: '#/components/schemas/rapidM2MStamp' };
|
|
@@ -179,6 +181,19 @@ function generateAPIFromMap(ddeMap, manifest, context = null) {
|
|
|
179
181
|
else {
|
|
180
182
|
Object.assign(apiDescription.components, structuredClone(defaultAppComponents));
|
|
181
183
|
}
|
|
184
|
+
const isAddon = manifest_1.Manifest.isAddon(manifest);
|
|
185
|
+
if (isAddon) {
|
|
186
|
+
// add addonUid parameter if this is an addon project
|
|
187
|
+
apiDescription.components.parameters['addonId'] = {
|
|
188
|
+
name: 'addonUid',
|
|
189
|
+
in: 'path',
|
|
190
|
+
description: 'The addon uid',
|
|
191
|
+
schema: {
|
|
192
|
+
type: 'string'
|
|
193
|
+
},
|
|
194
|
+
required: true
|
|
195
|
+
};
|
|
196
|
+
}
|
|
182
197
|
for (const containerDefinition of Object.values(ddeMap.containers)) {
|
|
183
198
|
if ((context &&
|
|
184
199
|
(!containerDefinition.libraries.includes(context) || containerDefinition.containerType === ContainerType.hx)) ||
|
|
@@ -188,10 +203,12 @@ function generateAPIFromMap(ddeMap, manifest, context = null) {
|
|
|
188
203
|
}
|
|
189
204
|
generateTagDescriptionFromContainer(apiDescription, containerDefinition);
|
|
190
205
|
generateSchemasFromContainer(apiDescription, containerDefinition, context);
|
|
191
|
-
generatePathInformationFromContainer(apiDescription, containerDefinition);
|
|
206
|
+
generatePathInformationFromContainer(apiDescription, containerDefinition, isAddon);
|
|
192
207
|
// legacy routes
|
|
193
|
-
|
|
194
|
-
|
|
208
|
+
if (!isAddon) {
|
|
209
|
+
generateLegacySchemasFromContainer(apiDescription, containerDefinition, context);
|
|
210
|
+
generateLegacyPathInformationFromContainer(apiDescription, containerDefinition);
|
|
211
|
+
}
|
|
195
212
|
}
|
|
196
213
|
return (0, yaml_1.stringify)(apiDescription);
|
|
197
214
|
}
|
|
@@ -434,10 +451,15 @@ function generateLegacyPathInformationFromContainer(apiDescription, containerDef
|
|
|
434
451
|
}
|
|
435
452
|
apiDescription.paths[apiPath] = apiPathMethods;
|
|
436
453
|
}
|
|
437
|
-
function generatePathInformationFromContainer(apiDescription, containerDefinition) {
|
|
454
|
+
function generatePathInformationFromContainer(apiDescription, containerDefinition, isAddonProject = false) {
|
|
438
455
|
const isTimeseriesContainer = containerDefinition.containerType === ContainerType.hx;
|
|
439
456
|
const containerType = isTimeseriesContainer ? 'timeseries' : 'containers';
|
|
440
|
-
const
|
|
457
|
+
const pathParameters = [contextIdRef];
|
|
458
|
+
let apiPath = `/api/1/sites/{siteUid}/${containerType}/${containerDefinition.title}`;
|
|
459
|
+
if (isAddonProject) {
|
|
460
|
+
apiPath = `/api/1/sites/{siteUid}/addons/{addonUid}/${containerType}/${containerDefinition.title}`;
|
|
461
|
+
pathParameters.push(addonIdRef);
|
|
462
|
+
}
|
|
441
463
|
const apiPathMethods = {
|
|
442
464
|
get: undefined,
|
|
443
465
|
put: undefined
|
|
@@ -445,7 +467,7 @@ function generatePathInformationFromContainer(apiDescription, containerDefinitio
|
|
|
445
467
|
const getMethod = {
|
|
446
468
|
tags: [tagNameFromContainerTitle(containerDefinition.title)],
|
|
447
469
|
summary: `Retrieve the data of the "${tagNameFromContainerTitle(containerDefinition.title)}" container`,
|
|
448
|
-
parameters: [
|
|
470
|
+
parameters: [...pathParameters],
|
|
449
471
|
responses: {
|
|
450
472
|
'200': {
|
|
451
473
|
...successfulOperationResponse,
|
|
@@ -478,7 +500,7 @@ function generatePathInformationFromContainer(apiDescription, containerDefinitio
|
|
|
478
500
|
apiPathMethods.put = {
|
|
479
501
|
tags: [tagNameFromContainerTitle(containerDefinition.title)],
|
|
480
502
|
summary: `Modify the data of the "${tagNameFromContainerTitle(containerDefinition.title)}" container`,
|
|
481
|
-
parameters: [
|
|
503
|
+
parameters: [...pathParameters],
|
|
482
504
|
requestBody: {
|
|
483
505
|
content: {
|
|
484
506
|
'application/json': {
|
|
@@ -506,7 +528,7 @@ function generatePathInformationFromContainer(apiDescription, containerDefinitio
|
|
|
506
528
|
tags: [tagNameFromContainerTitle(containerDefinition.title)],
|
|
507
529
|
summary: `Get the historical data of "${containerDefinition.title}"`,
|
|
508
530
|
parameters: [
|
|
509
|
-
|
|
531
|
+
...pathParameters,
|
|
510
532
|
{
|
|
511
533
|
name: 'json',
|
|
512
534
|
in: 'query',
|
|
@@ -101,6 +101,9 @@ function generateAutoIncFromMap(ddeMap, globalDefines, manifest) {
|
|
|
101
101
|
pwn(`#define ${name} ${quotes}${value}${quotes}`);
|
|
102
102
|
}
|
|
103
103
|
const { dpid, registry } = manifest;
|
|
104
|
+
if (!dpid) {
|
|
105
|
+
throw new Error('Setting "dpid" is required to generate dlo files');
|
|
106
|
+
}
|
|
104
107
|
const { auto_inc } = DeviceProfiles_1.DeviceProfiles[dpid];
|
|
105
108
|
addDefinition(`APM_DPID`, `${dpid}`);
|
|
106
109
|
addDefinition(`APM_DPID_${dpid}`, `1`);
|
package/out/main.js
CHANGED
|
@@ -22,6 +22,9 @@ const devPath = () => {
|
|
|
22
22
|
else if (process.env.NODE_ENV === 'local-dev-lib') {
|
|
23
23
|
return './dev/lib';
|
|
24
24
|
}
|
|
25
|
+
else if (process.env.NODE_ENV === 'local-dev-addon') {
|
|
26
|
+
return './dev/addon';
|
|
27
|
+
}
|
|
25
28
|
return '';
|
|
26
29
|
};
|
|
27
30
|
const cwd = vscode_uri_1.Utils.joinPath(vscode_uri_1.URI.file(process.cwd()), devPath());
|
package/out/manifest.js
CHANGED
|
@@ -12,8 +12,11 @@ const registryAPI_1 = require("./registryAPI");
|
|
|
12
12
|
const globals_1 = require("./globals");
|
|
13
13
|
const preload_1 = __importDefault(require("semver/preload"));
|
|
14
14
|
const DeviceProfiles_1 = require("./DeviceProfiles");
|
|
15
|
-
var isNumeric = helper_1.Helper.isNumeric;
|
|
16
15
|
const apm_1 = require("./package/apm");
|
|
16
|
+
var isNumeric = helper_1.Helper.isNumeric;
|
|
17
|
+
const PRODUCT_ID_SUPPORTED = '52v007';
|
|
18
|
+
// todo fill with actual version
|
|
19
|
+
const ADDON_SUPPORTED = '52v099';
|
|
17
20
|
// Cache to reduce the disk read requests
|
|
18
21
|
const manifestCache = {
|
|
19
22
|
_manifest: null,
|
|
@@ -43,6 +46,15 @@ var Manifest;
|
|
|
43
46
|
* The source filename where the information is stored in
|
|
44
47
|
*/
|
|
45
48
|
Manifest.fileName = 'studio.json';
|
|
49
|
+
let DeviceProfiles;
|
|
50
|
+
(function (DeviceProfiles) {
|
|
51
|
+
DeviceProfiles["m22x"] = "m22x";
|
|
52
|
+
DeviceProfiles["m23x"] = "m23x";
|
|
53
|
+
DeviceProfiles["nrf91"] = "nrf91";
|
|
54
|
+
DeviceProfiles["m2blegw"] = "m2blegw";
|
|
55
|
+
DeviceProfiles["m2easyv3"] = "m2easyv3";
|
|
56
|
+
DeviceProfiles["m2easyiot"] = "m2easyiot";
|
|
57
|
+
})(DeviceProfiles = Manifest.DeviceProfiles || (Manifest.DeviceProfiles = {}));
|
|
46
58
|
/**
|
|
47
59
|
* Type of the iot app project
|
|
48
60
|
*/
|
|
@@ -50,6 +62,7 @@ var Manifest;
|
|
|
50
62
|
(function (ProjectTypes) {
|
|
51
63
|
ProjectTypes["app"] = "app";
|
|
52
64
|
ProjectTypes["library"] = "library";
|
|
65
|
+
ProjectTypes["addon"] = "addon";
|
|
53
66
|
})(ProjectTypes = Manifest.ProjectTypes || (Manifest.ProjectTypes = {}));
|
|
54
67
|
let BloAccessLevel;
|
|
55
68
|
(function (BloAccessLevel) {
|
|
@@ -84,7 +97,7 @@ var Manifest;
|
|
|
84
97
|
}
|
|
85
98
|
Manifest.read = read;
|
|
86
99
|
/**
|
|
87
|
-
* Reads the studio.json as an
|
|
100
|
+
* Reads the studio.json as an Uint8Array
|
|
88
101
|
* @param cwd
|
|
89
102
|
* @param fs
|
|
90
103
|
*/
|
|
@@ -118,6 +131,22 @@ var Manifest;
|
|
|
118
131
|
}
|
|
119
132
|
}
|
|
120
133
|
Manifest.isLibrary = isLibrary;
|
|
134
|
+
/**
|
|
135
|
+
* Check if the current project is an addon project
|
|
136
|
+
* @param manifest
|
|
137
|
+
*/
|
|
138
|
+
function isAddon(manifest) {
|
|
139
|
+
return manifest.type === ProjectTypes.addon;
|
|
140
|
+
}
|
|
141
|
+
Manifest.isAddon = isAddon;
|
|
142
|
+
/**
|
|
143
|
+
* Check if the current project is an app project
|
|
144
|
+
* @param manifest
|
|
145
|
+
*/
|
|
146
|
+
function isApp(manifest) {
|
|
147
|
+
return manifest.type === ProjectTypes.app;
|
|
148
|
+
}
|
|
149
|
+
Manifest.isApp = isApp;
|
|
121
150
|
/**
|
|
122
151
|
* Validates if the properties within
|
|
123
152
|
* @param cwd
|
|
@@ -228,6 +257,30 @@ var Manifest;
|
|
|
228
257
|
return null;
|
|
229
258
|
}
|
|
230
259
|
Manifest.validateRegistryAllowedBackends = validateRegistryAllowedBackends;
|
|
260
|
+
const REGEX_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
261
|
+
async function validateRegistryAllowedApplications(allowedApplications) {
|
|
262
|
+
if (allowedApplications === undefined) {
|
|
263
|
+
return 'Allowed applications not specified yet';
|
|
264
|
+
}
|
|
265
|
+
if (allowedApplications === null) {
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
if (Array.isArray(allowedApplications) || allowedApplications?.includes(';')) {
|
|
269
|
+
const validationArray = allowedApplications?.includes(';')
|
|
270
|
+
? allowedApplications.split(';')
|
|
271
|
+
: allowedApplications;
|
|
272
|
+
for (const uid of validationArray) {
|
|
273
|
+
if (!uid.match(REGEX_UUID)) {
|
|
274
|
+
return `Application id "${uid}" is invalid`;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
else if (!allowedApplications?.match(REGEX_UUID) && allowedApplications !== '*') {
|
|
279
|
+
return `Invalid value for "allowedApplications"`;
|
|
280
|
+
}
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
Manifest.validateRegistryAllowedApplications = validateRegistryAllowedApplications;
|
|
231
284
|
async function validateApplicationIcon(cwd, fs, manifest) {
|
|
232
285
|
const iconPath = manifest.icon;
|
|
233
286
|
if (!iconPath) {
|
|
@@ -262,6 +315,7 @@ var Manifest;
|
|
|
262
315
|
throw new Error('Setting "engines.backend" is invalid');
|
|
263
316
|
}
|
|
264
317
|
validateHwFwOrProductId(manifest);
|
|
318
|
+
validateAddonSupported(manifest);
|
|
265
319
|
}
|
|
266
320
|
Manifest.validateEngineSettings = validateEngineSettings;
|
|
267
321
|
/**
|
|
@@ -275,9 +329,10 @@ var Manifest;
|
|
|
275
329
|
if (!manifest) {
|
|
276
330
|
manifest = await Manifest.read(cwd, fs);
|
|
277
331
|
}
|
|
332
|
+
const isAddon = Manifest.isAddon(manifest);
|
|
278
333
|
switch (apmPart) {
|
|
279
334
|
case apm_1.APM.Part.dlo:
|
|
280
|
-
return !!manifest?.dlo?.mainFile;
|
|
335
|
+
return !!manifest?.dlo?.mainFile && !isAddon;
|
|
281
336
|
case apm_1.APM.Part.blo:
|
|
282
337
|
return !!(manifest.blo?.buildCommand && manifest.blo?.workingPath);
|
|
283
338
|
case apm_1.APM.Part.pov:
|
|
@@ -324,13 +379,31 @@ function validateBLOSettings(manifest) {
|
|
|
324
379
|
}
|
|
325
380
|
function validateHwFwOrProductId(manifest) {
|
|
326
381
|
const { backend, productId, hwfw } = manifest.engines;
|
|
327
|
-
if (
|
|
382
|
+
if (Manifest.isAddon(manifest) && (productId || hwfw)) {
|
|
383
|
+
throw new Error('For project type "addon", "engines.hwfw" or "engines.productId" is not allowed!"');
|
|
384
|
+
}
|
|
385
|
+
if (backend && backend >= PRODUCT_ID_SUPPORTED) {
|
|
328
386
|
if (hwfw && productId) {
|
|
329
387
|
throw new Error('Only "engines.hwfw" or "engines.productId" is allowed!"');
|
|
330
388
|
}
|
|
331
389
|
}
|
|
332
390
|
else if (productId) {
|
|
333
|
-
throw new Error(
|
|
391
|
+
throw new Error(`"engines.productId" requires "engines.backend" to be "${PRODUCT_ID_SUPPORTED}"`);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
function validateAddonSupported(manifest) {
|
|
395
|
+
if (!Manifest.isAddon(manifest)) {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
const { backend } = manifest.engines;
|
|
399
|
+
if (!backend || backend < ADDON_SUPPORTED) {
|
|
400
|
+
throw new Error(`Project type "addon" requires "engines.backend" to be ">=${ADDON_SUPPORTED}"`);
|
|
401
|
+
}
|
|
402
|
+
if (manifest.dlo) {
|
|
403
|
+
throw new Error('For project type "addon", "dlo" is not supported!"');
|
|
404
|
+
}
|
|
405
|
+
if (manifest.dpid) {
|
|
406
|
+
throw new Error('For project type "addon", "dpid" is not supported!"');
|
|
334
407
|
}
|
|
335
408
|
}
|
|
336
409
|
/**
|
package/out/package/apm.js
CHANGED
|
@@ -31,30 +31,47 @@ var APM;
|
|
|
31
31
|
Part["blo"] = "blo";
|
|
32
32
|
Part["dfiles"] = "dfiles";
|
|
33
33
|
})(Part = APM.Part || (APM.Part = {}));
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
* @param fs
|
|
38
|
-
* @param phase
|
|
39
|
-
*/
|
|
40
|
-
async function createTag(cwd, fs, phase) {
|
|
41
|
-
const manifest = await manifest_1.Manifest.read(cwd, fs);
|
|
42
|
-
const { version, description, name, pov, engines, blo, publisher } = manifest;
|
|
34
|
+
function createBaseTagHeader(manifest) {
|
|
35
|
+
const { description, name, pov, engines, blo, publisher, type } = manifest;
|
|
36
|
+
const projectType = type || manifest_1.Manifest.ProjectTypes.app;
|
|
43
37
|
const tagHeader = {
|
|
44
38
|
name: name,
|
|
45
39
|
abstract: description,
|
|
46
|
-
phase: phase,
|
|
47
40
|
author: publisher || '',
|
|
48
41
|
pov_location: manifest_1.Manifest.PovLocation.embedded,
|
|
49
|
-
|
|
42
|
+
pov_details_lowlevel: false,
|
|
50
43
|
required_be: engines?.backend,
|
|
51
44
|
required_hwfw: engines?.hwfw?.join(';'),
|
|
52
45
|
required_productcode: engines?.productId?.join(';'),
|
|
53
|
-
blo_level: blo?.accessLevel || manifest_1.Manifest.BloAccessLevel.restricted
|
|
46
|
+
blo_level: blo?.accessLevel || manifest_1.Manifest.BloAccessLevel.restricted,
|
|
47
|
+
pip_id: ''
|
|
54
48
|
};
|
|
55
49
|
if (pov && pov.details) {
|
|
56
50
|
tagHeader.pov_location = manifest_1.Manifest.PovLocation.pure;
|
|
57
51
|
}
|
|
52
|
+
if (projectType === 'addon') {
|
|
53
|
+
tagHeader.required_hwfw = undefined;
|
|
54
|
+
tagHeader.required_productcode = undefined;
|
|
55
|
+
tagHeader.addon_max_sources = 1;
|
|
56
|
+
tagHeader.addon_max_per_site = 1;
|
|
57
|
+
}
|
|
58
|
+
return tagHeader;
|
|
59
|
+
}
|
|
60
|
+
APM.createBaseTagHeader = createBaseTagHeader;
|
|
61
|
+
/**
|
|
62
|
+
* Create new release tag
|
|
63
|
+
* @param cwd
|
|
64
|
+
* @param fs
|
|
65
|
+
* @param phase
|
|
66
|
+
*/
|
|
67
|
+
async function createTag(cwd, fs, phase) {
|
|
68
|
+
const manifest = await manifest_1.Manifest.read(cwd, fs);
|
|
69
|
+
const baseTagHeader = createBaseTagHeader(manifest);
|
|
70
|
+
const tagHeader = {
|
|
71
|
+
version: manifest.version,
|
|
72
|
+
...baseTagHeader,
|
|
73
|
+
phase: phase
|
|
74
|
+
};
|
|
58
75
|
return await createBuffer(cwd, fs, manifest, tagHeader);
|
|
59
76
|
}
|
|
60
77
|
APM.createTag = createTag;
|
|
@@ -65,23 +82,11 @@ var APM;
|
|
|
65
82
|
*/
|
|
66
83
|
async function createDevTag(cwd, fs) {
|
|
67
84
|
const manifest = await manifest_1.Manifest.read(cwd, fs);
|
|
68
|
-
const
|
|
85
|
+
const baseTag = createBaseTagHeader(manifest);
|
|
69
86
|
const apmTagHeader = {
|
|
70
|
-
|
|
71
|
-
author: publisher || '',
|
|
72
|
-
abstract: '',
|
|
73
|
-
blo_level: blo?.accessLevel || manifest_1.Manifest.BloAccessLevel.restricted,
|
|
74
|
-
pip_id: '',
|
|
75
|
-
pov_details_lowlevel: false,
|
|
76
|
-
pov_location: manifest_1.Manifest.PovLocation.embedded,
|
|
77
|
-
required_be: engines?.backend,
|
|
78
|
-
required_hwfw: engines?.hwfw?.join(';'),
|
|
79
|
-
required_productcode: engines?.productId?.join(';'),
|
|
87
|
+
...baseTag,
|
|
80
88
|
blo_autostart: false
|
|
81
89
|
};
|
|
82
|
-
if (manifest.pov?.details) {
|
|
83
|
-
apmTagHeader.pov_location = manifest_1.Manifest.PovLocation.pure;
|
|
84
|
-
}
|
|
85
90
|
return createBuffer(cwd, fs, manifest, apmTagHeader);
|
|
86
91
|
}
|
|
87
92
|
APM.createDevTag = createDevTag;
|
|
@@ -178,11 +183,17 @@ var APM;
|
|
|
178
183
|
const backendTarget = 'myDatanet';
|
|
179
184
|
const { publisher, name, description } = manifest;
|
|
180
185
|
const newApplication = {
|
|
186
|
+
// @ts-ignore
|
|
187
|
+
type: manifest.type || manifest_1.Manifest.ProjectTypes.app,
|
|
181
188
|
name: name,
|
|
182
189
|
targetSystem: backendTarget,
|
|
183
190
|
description: description || '',
|
|
184
191
|
allowedBackends: null
|
|
185
192
|
};
|
|
193
|
+
// initialize allowedApplications for addon
|
|
194
|
+
if (manifest_1.Manifest.isAddon(manifest)) {
|
|
195
|
+
newApplication.allowedApplications = null;
|
|
196
|
+
}
|
|
186
197
|
// create new application
|
|
187
198
|
const projectId = await registryAPI_1.Registry.createNewApplication(token, publisher, newApplication, env);
|
|
188
199
|
if (!projectId) {
|
package/out/package/package.js
CHANGED
|
@@ -171,6 +171,12 @@ var Package;
|
|
|
171
171
|
if (!manifest_1.Manifest.isLibrary(manifest)) {
|
|
172
172
|
await manifest_1.Manifest.validateApplicationIcon(cwd, fs, manifest);
|
|
173
173
|
manifest_1.Manifest.validateEngineSettings(manifest);
|
|
174
|
+
// validate for dpid
|
|
175
|
+
if (manifest_1.Manifest.isApp(manifest) &&
|
|
176
|
+
(await manifest_1.Manifest.isApmPartEnabled(cwd, fs, apm_1.APM.Part.dlo, manifest)) &&
|
|
177
|
+
(!manifest.dpid || !Object.values(manifest_1.Manifest.DeviceProfiles).includes(manifest.dpid))) {
|
|
178
|
+
throw new Error(`dpid: The device profile is needed to compile a dlo`);
|
|
179
|
+
}
|
|
174
180
|
}
|
|
175
181
|
}
|
|
176
182
|
Package.validatePublishSettings = validatePublishSettings;
|
|
@@ -204,8 +210,10 @@ async function buildDDE(cwd, fs) {
|
|
|
204
210
|
await dde_1.DDE.exportHistoryJson(cwd, fs, result.ddeJSON);
|
|
205
211
|
}
|
|
206
212
|
await dde_1.DDE.exportOpenApi(cwd, fs, result.ddeJSON);
|
|
207
|
-
await
|
|
208
|
-
|
|
213
|
+
if (await manifest_1.Manifest.isApmPartEnabled(cwd, fs, apm_1.APM.Part.dlo, manifest)) {
|
|
214
|
+
await dde_1.DDE.exportAutoDloFiles(cwd, fs, result.ddeJSON);
|
|
215
|
+
await dlo_1.DLO.exportDloConfig(cwd, fs);
|
|
216
|
+
}
|
|
209
217
|
}
|
|
210
218
|
else {
|
|
211
219
|
throw new Error('Project has errors!');
|
package/package.json
CHANGED
package/studio-cli-addon
ADDED