@microtronics/studio-cli 0.29.4 → 0.31.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 CHANGED
@@ -1,10 +1,35 @@
1
1
 
2
2
 
3
- ## 0.29.4 (2025-04-25)
3
+ ## 0.31.0 (2025-05-05)
4
4
 
5
5
 
6
- ### Bug Fixes
6
+ ### Features
7
7
 
8
+ * replace tarballjs with @gera2ld/tarjs ([b32454e](https://bitbucket.org/microtronics-core/vscode-studio/commits/b32454e04a5cd8f21ebb1e91f75fbe062fc593d8))
9
+ * **studio-cli:** add package path autodetection with "*" ([868b035](https://bitbucket.org/microtronics-core/vscode-studio/commits/868b03564dc9e3b31eb279d72826b17f1333503b))
10
+ * **studio-cli:** add support for publishing from archive ([79ef977](https://bitbucket.org/microtronics-core/vscode-studio/commits/79ef97783a56ce440e53e82dabd621db65c54637))
11
+ * **studio-cli:** support library publishing from package ([c731637](https://bitbucket.org/microtronics-core/vscode-studio/commits/c731637960a4de698eec5447005287a16b4cf73a))
12
+
13
+ ## 0.30.0 (2025-05-05)
14
+
15
+
16
+ ### Features
17
+
18
+ * **studio-cli:** add support for packaging app projects ([280115f](https://bitbucket.org/microtronics-core/vscode-studio/commits/280115fa77afb78754884a4eb83bd0365ff5b319))
19
+ * **studio-cli:** add support for packaging library projects ([1888df1](https://bitbucket.org/microtronics-core/vscode-studio/commits/1888df1b5d8c2f53a9705756d28d42360109e3ba))
20
+
21
+
22
+ ### Bug Fixes
23
+
24
+ * **studio-cli:** ensure dist/dlo directory is created on compile ([f110636](https://bitbucket.org/microtronics-core/vscode-studio/commits/f110636fc5042a5e25cc2d26fc98df4356d706bb))
25
+ * **studio-cli:** rename method in CustomWasmFS ([c3e1a22](https://bitbucket.org/microtronics-core/vscode-studio/commits/c3e1a227d7e57e91f9ddea45f11412ed59f71614))
26
+ * **studio-cli:** run dlo compiler relative to the cwd ([110b476](https://bitbucket.org/microtronics-core/vscode-studio/commits/110b4767bda8134aca2781c51f6e06bf800c4c67))
27
+
28
+ ## 0.29.4 (2025-04-25)
29
+
30
+
31
+ ### Bug Fixes
32
+
8
33
  * **studio-cli:** always use a clean app version as reference for dde generation ([da0b45b](https://bitbucket.org/microtronics-core/vscode-studio/commits/da0b45b5d9482056b3ead821e5b20e4083f4f06e))
9
34
 
10
35
  ## 0.29.3 (2025-04-25)
@@ -1807,48 +1807,17 @@ declare class DloCompiler {
1807
1807
  private cwd;
1808
1808
  private fs;
1809
1809
  private logger;
1810
- private preCompiler;
1811
1810
  private dloCC;
1812
1811
  private stdout;
1813
1812
  private stderr;
1814
1813
  constructor(cwd: URI, fs: LocalFS, logger: Log.Logger);
1815
1814
  private initDloCC;
1816
- private get MEMFS();
1817
1815
  compile(cwd: URI, fs: LocalFS): Promise<{
1818
1816
  code: number;
1819
1817
  stdout: string[];
1820
1818
  stderr: string[];
1821
1819
  diagnostics: Diagnostics.File[];
1822
1820
  }>;
1823
- private persistGeneratedFiles;
1824
- /**
1825
- * Search for all dlo files and persist it to the MEMFS
1826
- * @param cwd
1827
- * @param fs
1828
- * @param manifest
1829
- * @private
1830
- */
1831
- /**
1832
- * Precompile the given file and pass it to the MEMFS
1833
- * @param cwd
1834
- * @param manifest
1835
- * @param file
1836
- * @param stringBlob
1837
- */
1838
- memFSwriteFile(cwd: URI, manifest: Manifest.Manifest, file: URI, stringBlob: string[]): Promise<Diagnostics.File[]>;
1839
- /**
1840
- * Move a file within the MEMFS
1841
- * @param oldUri
1842
- * @param newUri
1843
- */
1844
- memFSmove(oldUri: URI, newUri: URI): Promise<void>;
1845
- /**
1846
- * Remove a file from the MEMFS
1847
- * @param uri
1848
- */
1849
- memFSunlink(uri: URI): Promise<void>;
1850
- private memFSmkdir;
1851
- private memFSstat;
1852
1821
  /**
1853
1822
  * Get a symbol compiler instance
1854
1823
  */
@@ -2101,7 +2070,7 @@ export declare namespace Library {
2101
2070
  * @param archive
2102
2071
  * @param env
2103
2072
  */
2104
- export function publishPackage(cwd: URI, fs: LocalFS, token: Registry.AuthToken, archive: Uint8Array, env?: Globals.ENV): Promise<void>;
2073
+ export function publishPackage(token: Registry.AuthToken, manifest: Manifest.Manifest, archive: Uint8Array, env?: Globals.ENV): Promise<void>;
2105
2074
  }
2106
2075
 
2107
2076
  declare interface LocalFS {
@@ -2146,6 +2115,12 @@ declare interface LocalFS {
2146
2115
  * @param target The destination location.
2147
2116
  */
2148
2117
  copy: (source: URI, target: URI) => Promise<any>;
2118
+ /**
2119
+ * Create a new directory
2120
+ *
2121
+ * @param path The directory path that should be created.
2122
+ */
2123
+ mkdir: (path: URI) => Promise<any>;
2149
2124
  }
2150
2125
 
2151
2126
  export declare namespace Log {
@@ -2319,6 +2294,19 @@ export declare namespace Manifest {
2319
2294
  export function isApmPartEnabled(cwd: URI, fs: LocalFS, apmPart: APM.Part, manifest?: Manifest.Manifest): Promise<boolean>;
2320
2295
  }
2321
2296
 
2297
+ /**
2298
+ * Packs the given directory into a deployable package using the specified configuration.
2299
+ *
2300
+ * @param {URI} cwd - The current working directory URI where the package is located.
2301
+ * @param {LocalFS} fs - The file system interface to perform file-related operations.
2302
+ * @param {Log.Logger} logger - The logger instance for logging activity during the packaging process.
2303
+ * @param {Globals.ENV} env - The environment variables and settings to use during packaging.
2304
+ * @param {string | null} apiToken - The API token used for authentication, if required.
2305
+ * @param {APM.TagPhase} [optsPhase] - An optional tag phase for the package tagging process.
2306
+ * @return {Promise<Package>} A promise that resolves to the packaged result.
2307
+ */
2308
+ export declare function pack(cwd: URI, fs: LocalFS, logger: Log.Logger, env: Globals.ENV, apiToken: string | null, optsPhase?: APM.TagPhase): Promise<void>;
2309
+
2322
2310
  export declare namespace Package {
2323
2311
  export interface MergedDiagnostics {
2324
2312
  [APM.Part.dde]: Diagnostics.File[];
@@ -2350,6 +2338,7 @@ export declare namespace Package {
2350
2338
  * @param env
2351
2339
  */
2352
2340
  export function release(cwd: URI, fs: LocalFS, logger: Log.Logger, env: Globals.ENV, token: Registry.AuthToken, releasePhase?: APM.TagPhase, allowedBackends?: Registry.ApiNewApplication['allowedBackends']): Promise<void>;
2341
+ export function pack(cwd: URI, fs: LocalFS, logger: Log.Logger, env: Globals.ENV, token: Registry.AuthToken, releasePhase?: APM.TagPhase): Promise<void>;
2353
2342
  /**
2354
2343
  * Publish an application model tag
2355
2344
  * @param cwd
@@ -2370,6 +2359,21 @@ export declare namespace Package {
2370
2359
  * @param env
2371
2360
  */
2372
2361
  export function releaseLibrary(cwd: URI, fs: LocalFS, logger: Log.Logger, token: Registry.AuthToken, env: Globals.ENV): Promise<void>;
2362
+ /**
2363
+ * Publishes an archive package to the appropriate library or application registry.
2364
+ *
2365
+ * @param {URI} cwd - The current working directory where the package archive is located.
2366
+ * @param {LocalFS} fs - The file system interface for reading and writing files.
2367
+ * @param {Log.Logger} logger - The logger instance for logging messages during the operation.
2368
+ * @param {Registry.AuthToken} token - The authorization token required for interacting with the registry.
2369
+ * @param {Globals.ENV} env - The global environment settings.
2370
+ * @param {string} packagePath - The relative path to the archive package to be published.
2371
+ * @param {APM.TagPhase} [releasePhase] - An optional release phase for tagging the published version of the application.
2372
+ * @param {Registry.ApiNewApplication['allowedBackends']} [allowedBackends] - An optional list of allowed backends for the published version.
2373
+ *
2374
+ * @return {Promise<void>} A promise that resolves when the publication process completes successfully.
2375
+ */
2376
+ export function publishArchive(cwd: URI, fs: LocalFS, logger: Log.Logger, token: Registry.AuthToken, env: Globals.ENV, packagePath: string, releasePhase?: APM.TagPhase, allowedBackends?: Registry.ApiNewApplication['allowedBackends']): Promise<void>;
2373
2377
  /**
2374
2378
  * Read the projects README.md file
2375
2379
  * validates if the file content is the initial content
@@ -2393,9 +2397,12 @@ export declare namespace Package {
2393
2397
  * @param env
2394
2398
  */
2395
2399
  export function validatePublishSettings(cwd: URI, fs: LocalFS, token: Registry.AuthToken, env: Globals.ENV): Promise<void>;
2400
+ export function readFilesFromTarGz(gzipped: Uint8Array, fileNames: string[]): Promise<{
2401
+ [key: string]: Blob;
2402
+ }>;
2396
2403
  }
2397
2404
 
2398
- declare function parseWarningsAndErrors(stderr: string[], relatedFile?: URI): Diagnostics.File[];
2405
+ declare function parseWarningsAndErrors(cwd: URI, stderr: string[], relatedFile?: URI): Diagnostics.File[];
2399
2406
 
2400
2407
  /**
2401
2408
  * This file was auto-generated by openapi-typescript.
@@ -4614,9 +4621,10 @@ declare interface paths {
4614
4621
  * @param {string | null} apiToken - The API token for authentication, or null if not applicable.
4615
4622
  * @param {string | undefined} optsAllowedBackends - A semicolon-separated list of allowed backends, or '*' to allow all, or undefined if not specified.
4616
4623
  * @param {APM.TagPhase} optsPhase - The release phase tag associated with the package publishing.
4624
+ * @param {string }packagePath - The path to the package to be published. If not provided, the package will be published using the default settings.
4617
4625
  * @return {Promise<void>} A promise that resolves when the package has been successfully published or rejects with an error if the process fails.
4618
4626
  */
4619
- export declare function publish(cwd: URI, fs: LocalFS, logger: Log.Logger, env: Globals.ENV, apiToken: string | null, optsAllowedBackends: string | undefined, optsPhase?: APM.TagPhase): Promise<void>;
4627
+ export declare function publish(cwd: URI, fs: LocalFS, logger: Log.Logger, env: Globals.ENV, apiToken: string | null, optsAllowedBackends: string | undefined, optsPhase?: APM.TagPhase, packagePath?: string): Promise<void>;
4620
4628
 
4621
4629
  export declare namespace Registry {
4622
4630
  export type AuthToken = string | null;
package/out/api.js CHANGED
@@ -4,6 +4,7 @@ exports.Log = exports.ENV = exports.DFILES = exports.Library = exports.APM = exp
4
4
  exports.install = install;
5
5
  exports.build = build;
6
6
  exports.publish = publish;
7
+ exports.pack = pack;
7
8
  const dependencies_1 = require("./dependencies");
8
9
  Object.defineProperty(exports, "Dependencies", { enumerable: true, get: function () { return dependencies_1.Dependencies; } });
9
10
  const manifest_1 = require("./manifest");
@@ -79,6 +80,26 @@ async function install(cwd, fs, env, apiToken, dependencies) {
79
80
  async function build(cwd, fs, logger, env, apiToken = null, selectedParts = true, errorWithDiagnostics) {
80
81
  return package_1.Package.buildAll(cwd, fs, logger, env, apiToken, selectedParts, errorWithDiagnostics);
81
82
  }
83
+ /**
84
+ * Parses and validates the allowed backends configuration.
85
+ *
86
+ * @param {string | undefined} optsAllowedBackends - A string defining allowed backends,
87
+ * either as a semicolon-separated list of backends or the wildcard '*'. It may also be undefined.
88
+ * @return {Promise<Registry.ApiNewApplication['allowedBackends']>} A promise that resolves to
89
+ * an array of allowed backends or null if none are provided.
90
+ * @throws {Error} Throws an error if the validation of the allowed backends fails.
91
+ */
92
+ async function parseAllowedBackends(optsAllowedBackends) {
93
+ let allowedBackends = null;
94
+ if (optsAllowedBackends) {
95
+ allowedBackends = optsAllowedBackends === '*' ? optsAllowedBackends : optsAllowedBackends.split(';');
96
+ const errorMessage = await manifest_1.Manifest.validateRegistryAllowedBackends(allowedBackends);
97
+ if (errorMessage) {
98
+ throw new Error(errorMessage);
99
+ }
100
+ }
101
+ return allowedBackends;
102
+ }
82
103
  /**
83
104
  * Publishes a package to the registry with the specified settings and configurations.
84
105
  *
@@ -89,18 +110,32 @@ async function build(cwd, fs, logger, env, apiToken = null, selectedParts = true
89
110
  * @param {string | null} apiToken - The API token for authentication, or null if not applicable.
90
111
  * @param {string | undefined} optsAllowedBackends - A semicolon-separated list of allowed backends, or '*' to allow all, or undefined if not specified.
91
112
  * @param {APM.TagPhase} optsPhase - The release phase tag associated with the package publishing.
113
+ * @param {string }packagePath - The path to the package to be published. If not provided, the package will be published using the default settings.
92
114
  * @return {Promise<void>} A promise that resolves when the package has been successfully published or rejects with an error if the process fails.
93
115
  */
94
- async function publish(cwd, fs, logger, env, apiToken, optsAllowedBackends, optsPhase) {
116
+ async function publish(cwd, fs, logger, env, apiToken, optsAllowedBackends, optsPhase, packagePath) {
95
117
  logger.info('Publishing package...');
96
- let allowedBackends = null;
97
- if (optsAllowedBackends) {
98
- allowedBackends = optsAllowedBackends === '*' ? optsAllowedBackends : optsAllowedBackends.split(';');
99
- const errorMessage = await manifest_1.Manifest.validateRegistryAllowedBackends(allowedBackends);
100
- if (errorMessage) {
101
- throw new Error(errorMessage);
102
- }
118
+ const allowedBackends = await parseAllowedBackends(optsAllowedBackends);
119
+ if (packagePath) {
120
+ await package_1.Package.publishArchive(cwd, fs, logger, apiToken, env, packagePath, optsPhase, allowedBackends);
121
+ }
122
+ else {
123
+ await package_1.Package.validatePublishSettings(cwd, fs, apiToken, env);
124
+ return package_1.Package.release(cwd, fs, logger, env, apiToken, optsPhase, allowedBackends);
103
125
  }
104
- return package_1.Package.release(cwd, fs, logger, env, apiToken, optsPhase, allowedBackends);
126
+ }
127
+ /**
128
+ * Packs the given directory into a deployable package using the specified configuration.
129
+ *
130
+ * @param {URI} cwd - The current working directory URI where the package is located.
131
+ * @param {LocalFS} fs - The file system interface to perform file-related operations.
132
+ * @param {Log.Logger} logger - The logger instance for logging activity during the packaging process.
133
+ * @param {Globals.ENV} env - The environment variables and settings to use during packaging.
134
+ * @param {string | null} apiToken - The API token used for authentication, if required.
135
+ * @param {APM.TagPhase} [optsPhase] - An optional tag phase for the package tagging process.
136
+ * @return {Promise<Package>} A promise that resolves to the packaged result.
137
+ */
138
+ async function pack(cwd, fs, logger, env, apiToken, optsPhase) {
139
+ return package_1.Package.pack(cwd, fs, logger, env, apiToken, optsPhase);
105
140
  }
106
141
  //# sourceMappingURL=api.js.map
package/out/cliFS.js CHANGED
@@ -66,6 +66,9 @@ exports.cliFS = {
66
66
  else {
67
67
  return promises_1.default.copyFile(source.fsPath, target.fsPath);
68
68
  }
69
+ },
70
+ async mkdir(path) {
71
+ await promises_1.default.mkdir(path.fsPath, { recursive: true });
69
72
  }
70
73
  };
71
74
  //# sourceMappingURL=cliFS.js.map
@@ -25,6 +25,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.CUSTOM_WASM_FS = exports.precompilerDiagnostics = void 0;
27
27
  exports.uriToMemFsPath = uriToMemFsPath;
28
+ exports.relativeMemFsPath = relativeMemFsPath;
28
29
  const nodeFs = __importStar(require("fs"));
29
30
  const vscode_uri_1 = require("vscode-uri");
30
31
  const preCompiler_1 = require("./preCompiler");
@@ -62,6 +63,25 @@ const CUSTOM_WASM_FS = (FS, cwd, manifest) => {
62
63
  ctime: stat.ctime
63
64
  };
64
65
  },
66
+ setattr(node, attr) {
67
+ const path = vscode_uri_1.Utils.joinPath(vscode_uri_1.URI.parse(node.mount.opts.root), FS.getPath(node)).fsPath;
68
+ if (!nodeFs.existsSync(path)) {
69
+ throw new FS.ErrnoError(44 /* ENOENT */);
70
+ }
71
+ // Change file size (truncate/grow)
72
+ if (typeof attr.size === 'number') {
73
+ nodeFs.truncateSync(path, attr.size);
74
+ }
75
+ // Change file mode (permissions)
76
+ if (typeof attr.mode === 'number') {
77
+ nodeFs.chmodSync(path, attr.mode);
78
+ }
79
+ // Change access/modification time
80
+ if (attr.atime || attr.mtime) {
81
+ const stat = nodeFs.statSync(path);
82
+ nodeFs.utimesSync(path, attr.atime ?? stat.atime, attr.mtime ?? stat.mtime);
83
+ }
84
+ },
65
85
  lookup(parent, name) {
66
86
  const currPath = vscode_uri_1.Utils.joinPath(vscode_uri_1.URI.parse(parent.mount.opts.root), FS.getPath(parent), name);
67
87
  const path = currPath.fsPath;
@@ -81,7 +101,10 @@ const CUSTOM_WASM_FS = (FS, cwd, manifest) => {
81
101
  mknod(parent, name, mode, dev) {
82
102
  const path = vscode_uri_1.Utils.joinPath(vscode_uri_1.URI.parse(parent.mount.opts.root), FS.getPath(parent), name).fsPath;
83
103
  nodeFs.writeFileSync(path, '');
84
- return FS.createNode(parent, name, mode, dev);
104
+ const node = FS.createNode(parent, name, mode, dev);
105
+ node.node_ops = parent.node_ops;
106
+ node.stream_ops = parent.stream_ops;
107
+ return node;
85
108
  },
86
109
  unlink(parent, name) {
87
110
  const path = vscode_uri_1.Utils.joinPath(vscode_uri_1.URI.parse(parent.mount.opts.root), FS.getPath(parent), name).fsPath;
@@ -90,14 +113,17 @@ const CUSTOM_WASM_FS = (FS, cwd, manifest) => {
90
113
  mkdir(parent, name, mode) {
91
114
  const path = vscode_uri_1.Utils.joinPath(vscode_uri_1.URI.parse(parent.mount.opts.root), FS.getPath(parent), name).fsPath;
92
115
  nodeFs.mkdirSync(path, { mode });
93
- return FS.createNode(parent, name, mode | MODE_DIR, 0);
116
+ const node = FS.createNode(parent, name, mode | MODE_DIR, 0);
117
+ node.node_ops = parent.node_ops;
118
+ node.stream_ops = parent.stream_ops;
119
+ return node;
94
120
  },
95
121
  rmdir(parent, name) {
96
122
  const path = vscode_uri_1.Utils.joinPath(vscode_uri_1.URI.parse(parent.mount.opts.root), FS.getPath(parent), name).fsPath;
97
123
  nodeFs.rmdirSync(path);
98
124
  },
99
- rename(oldParent, oldName, newParent, newName) {
100
- const oldPath = vscode_uri_1.Utils.joinPath(vscode_uri_1.URI.parse(oldParent.mount.opts.root), FS.getPath(oldParent), oldName).fsPath;
125
+ rename(oldParent, newParent, newName) {
126
+ const oldPath = vscode_uri_1.Utils.joinPath(vscode_uri_1.URI.parse(oldParent.mount.opts.root), FS.getPath(oldParent)).fsPath;
101
127
  const newPath = vscode_uri_1.Utils.joinPath(vscode_uri_1.URI.parse(newParent.mount.opts.root), FS.getPath(newParent), newName).fsPath;
102
128
  nodeFs.renameSync(oldPath, newPath);
103
129
  }
@@ -224,4 +250,9 @@ function precompileRequestedDloFile(cwd, manifest, filePath) {
224
250
  function uriToMemFsPath(path) {
225
251
  return path.fsPath.replace(/\\/g, '/');
226
252
  }
253
+ function relativeMemFsPath(cwd, path) {
254
+ const cwdPath = uriToMemFsPath(cwd);
255
+ const fsPath = uriToMemFsPath(path);
256
+ return fsPath.replace(cwdPath, '');
257
+ }
227
258
  //# sourceMappingURL=CustomWasmFS.js.map
@@ -1,37 +1,12 @@
1
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
2
  Object.defineProperty(exports, "__esModule", { value: true });
26
3
  exports.DloCompiler = void 0;
27
4
  exports.parseWarningsAndErrors = parseWarningsAndErrors;
28
5
  exports.generateConfigFile = generateConfigFile;
29
- const preCompiler_1 = require("./preCompiler");
30
6
  const vscode_uri_1 = require("vscode-uri");
31
7
  const manifest_1 = require("../manifest");
32
8
  const defaultFiles_1 = require("../defaultFiles");
33
9
  const dependencies_1 = require("../dependencies");
34
- const iconv = __importStar(require("iconv-lite"));
35
10
  const apm_1 = require("../package/apm");
36
11
  const CustomWasmFS_1 = require("./CustomWasmFS");
37
12
  const DLO_MODULE = require('./dlocc.js');
@@ -39,7 +14,6 @@ class DloCompiler {
39
14
  cwd;
40
15
  fs;
41
16
  logger;
42
- preCompiler = new preCompiler_1.DloPreCompiler();
43
17
  dloCC;
44
18
  stdout = [];
45
19
  stderr = [];
@@ -55,16 +29,18 @@ class DloCompiler {
55
29
  this.dloCC = await DLO_MODULE({
56
30
  noExitRuntime: noExit,
57
31
  print: (data) => {
58
- this.logger.log(data);
32
+ const patched = parseCompilerMessage(this.cwd, data);
33
+ this.logger.log(patched ? patched.message : data);
59
34
  this.stdout.push(data);
60
35
  },
61
36
  printErr: (err) => {
37
+ const patched = parseCompilerMessage(this.cwd, err);
62
38
  // filter for warn messages
63
39
  if (err.includes(': warning')) {
64
- this.logger.warn(err);
40
+ this.logger.warn(patched ? patched.message : err);
65
41
  }
66
42
  else {
67
- this.logger.error(err);
43
+ this.logger.error(patched ? patched.message : err);
68
44
  }
69
45
  this.stderr.push(err);
70
46
  this.stdout.push(err);
@@ -78,9 +54,8 @@ class DloCompiler {
78
54
  FS.filesystems.NODEFS_TS = (0, CustomWasmFS_1.CUSTOM_WASM_FS)(FS, this.cwd, manifest);
79
55
  FS.mkdir(rootDir);
80
56
  FS.mount(FS.filesystems.NODEFS_TS, { root: '/' }, rootDir);
81
- }
82
- get MEMFS() {
83
- return this.dloCC.FS;
57
+ // Set the current working directory to the root directory
58
+ FS.chdir((0, CustomWasmFS_1.uriToMemFsPath)(this.cwd));
84
59
  }
85
60
  async compile(cwd, fs) {
86
61
  const manifest = await manifest_1.Manifest.read(cwd, fs);
@@ -94,18 +69,17 @@ class DloCompiler {
94
69
  };
95
70
  }
96
71
  await this.initDloCC();
72
+ await fs.mkdir(vscode_uri_1.Utils.joinPath(cwd, 'dist/dlo'));
97
73
  const mainFile = vscode_uri_1.Utils.joinPath(cwd, manifest.dlo?.mainFile || defaultFiles_1.DefaultFiles.filePaths.dlo.mainDLO);
98
74
  const options = [];
99
75
  // read config file
100
76
  const configFilePath = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.cfg);
101
- options.push(`-T${(0, CustomWasmFS_1.uriToMemFsPath)(configFilePath)}`);
77
+ const configFile = (0, CustomWasmFS_1.relativeMemFsPath)(cwd, configFilePath);
78
+ options.push(`-T.${configFile}`);
102
79
  let exitCode = 0;
103
80
  try {
104
- exitCode = await this.dloCC.callMain([(0, CustomWasmFS_1.uriToMemFsPath)(mainFile), ...options]);
105
- // compiler doesn't have any errors
106
- if (exitCode === 0) {
107
- await this.persistGeneratedFiles(cwd, fs, mainFile);
108
- }
81
+ const mainFilePath = `.${(0, CustomWasmFS_1.relativeMemFsPath)(cwd, mainFile)}`;
82
+ exitCode = await this.dloCC.callMain([mainFilePath, ...options]);
109
83
  }
110
84
  catch (e) {
111
85
  this.logger.error(e);
@@ -114,109 +88,9 @@ class DloCompiler {
114
88
  code: exitCode,
115
89
  stdout: this.stdout,
116
90
  stderr: this.stderr,
117
- diagnostics: [...CustomWasmFS_1.precompilerDiagnostics, ...parseWarningsAndErrors(this.stderr, mainFile)]
91
+ diagnostics: [...CustomWasmFS_1.precompilerDiagnostics, ...parseWarningsAndErrors(cwd, this.stderr, mainFile)]
118
92
  };
119
93
  }
120
- async persistGeneratedFiles(cwd, fs, mainFile) {
121
- const baseName = vscode_uri_1.Utils.basename(mainFile).split('.')[0];
122
- const possibleFiles = this.MEMFS.readdir('/');
123
- for (const fileName of possibleFiles) {
124
- if (fileName.startsWith(baseName)) {
125
- const blob = this.MEMFS.readFile(fileName);
126
- const distPath = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.dist.dloPath, fileName);
127
- await fs.writeFile(distPath, blob);
128
- }
129
- }
130
- }
131
- /**
132
- * Search for all dlo files and persist it to the MEMFS
133
- * @param cwd
134
- * @param fs
135
- * @param manifest
136
- * @private
137
- */
138
- /* private async persistDloFiles(cwd: URI, fs: LocalFS, manifest: Manifest.Manifest) {
139
- const files = await fs.findFiles(cwd, '**!/!*.{dlo,inc}');
140
- const precompilerDiagnostics: Diagnostics.File[] = [];
141
- // add dlo.cfg file to the file list
142
- for (const file of files) {
143
- if (await fs.stat(file)) {
144
- const content = await fs.readFile(file);
145
- const stringBlob = convertBlobToStringArray(content);
146
- const diagnostics = await this.memFSwriteFile(cwd, manifest, file, stringBlob);
147
- precompilerDiagnostics.push(...diagnostics);
148
- }
149
- }
150
- return precompilerDiagnostics;
151
- }*/
152
- /**
153
- * Precompile the given file and pass it to the MEMFS
154
- * @param cwd
155
- * @param manifest
156
- * @param file
157
- * @param stringBlob
158
- */
159
- async memFSwriteFile(cwd, manifest, file, stringBlob) {
160
- const precompilerDiagnostics = [];
161
- const preCompiled = this.preCompiler.preCompileDloFile(cwd, manifest, file, stringBlob);
162
- precompilerDiagnostics.push(...preCompiled.diagnostics);
163
- this.memFSmkdir(file);
164
- this.MEMFS.writeFile((0, CustomWasmFS_1.uriToMemFsPath)(file), iconv.encode(preCompiled.data, 'cp1252'));
165
- return precompilerDiagnostics;
166
- }
167
- /**
168
- * Move a file within the MEMFS
169
- * @param oldUri
170
- * @param newUri
171
- */
172
- async memFSmove(oldUri, newUri) {
173
- try {
174
- this.memFSmkdir(newUri);
175
- this.MEMFS.rename((0, CustomWasmFS_1.uriToMemFsPath)(oldUri), (0, CustomWasmFS_1.uriToMemFsPath)(newUri));
176
- }
177
- catch (e) {
178
- this.logger.error('memFSmove', e);
179
- }
180
- }
181
- /**
182
- * Remove a file from the MEMFS
183
- * @param uri
184
- */
185
- async memFSunlink(uri) {
186
- try {
187
- this.MEMFS.unlink((0, CustomWasmFS_1.uriToMemFsPath)(uri));
188
- }
189
- catch (e) {
190
- this.logger.error('memFSunlink', e);
191
- }
192
- }
193
- memFSmkdir(uri) {
194
- const split = (0, CustomWasmFS_1.uriToMemFsPath)(vscode_uri_1.Utils.dirname(uri)).split('/');
195
- let dirname = '';
196
- split.forEach(folder => {
197
- if (!folder) {
198
- return;
199
- }
200
- try {
201
- dirname += `${folder}/`;
202
- if (!this.memFSstat(dirname)) {
203
- this.MEMFS.mkdir(dirname);
204
- }
205
- }
206
- catch (e) {
207
- this.logger.error('memFSmkdir', e);
208
- }
209
- });
210
- }
211
- memFSstat(dirname) {
212
- try {
213
- this.MEMFS.stat(dirname);
214
- return true;
215
- }
216
- catch (e) {
217
- return false;
218
- }
219
- }
220
94
  //Symbol Compiler handling
221
95
  /**
222
96
  * Get a symbol compiler instance
@@ -253,7 +127,7 @@ class DloCompiler {
253
127
  }
254
128
  }
255
129
  exports.DloCompiler = DloCompiler;
256
- function parseWarningsAndErrors(stderr, relatedFile) {
130
+ function parseWarningsAndErrors(cwd, stderr, relatedFile) {
257
131
  const compilerDiagnostics = [];
258
132
  const messages = stderr.filter(line => !!line.trim());
259
133
  for (const message of messages) {
@@ -266,35 +140,44 @@ function parseWarningsAndErrors(stderr, relatedFile) {
266
140
  });
267
141
  continue;
268
142
  }
269
- // regular error/warning - such as:
270
- // C:\Users\aai\rmstudio\apmparts\dlo-pawn\stdlib\rm-dde.inc(392) : error 036: empty statement
271
- // main.p(138) : warning 203: symbol is never used: "log_str"
272
- // main.p(6) : fatal error 100: cannot read from file: "oTests/module_t"
273
- const i0 = message.indexOf(' : ');
274
- const i1 = message.indexOf(': ', i0 + 3);
275
- const fileNameAndLineNumber = message.substring(0, i0).trim();
276
- const levelAndCode = message.substring(i0 + 3, i1).trim();
277
- const msg = message.substring(i1 + 2).trim();
278
- // ignore lines which do not contain err/warn msg (or are empty)
279
- if (!fileNameAndLineNumber || !levelAndCode || !msg) {
143
+ const parsedMessage = parseCompilerMessage(cwd, message);
144
+ if (!parsedMessage) {
280
145
  continue;
281
146
  }
282
- const [fileName, lineNumber] = fileNameAndLineNumber.split(/[()(-)]/);
283
- const decodeLevelAndCode = levelAndCode.split(' ');
284
- const level = decodeLevelAndCode[decodeLevelAndCode.length - 2]; //lvl is always the second last
285
- let posix = fileName.replace(/\\/g, '/');
286
- if (posix.startsWith('/')) {
287
- posix = posix.substring(1);
288
- }
289
147
  compilerDiagnostics.push({
290
- file: vscode_uri_1.URI.parse(`file:///${posix}`),
291
- level,
292
- line: Number(lineNumber) - 1,
293
- message: msg
148
+ file: vscode_uri_1.URI.parse(`file:///${parsedMessage?.posixPath}`),
149
+ level: parsedMessage.level,
150
+ line: Number(parsedMessage.lineNumber) - 1,
151
+ message: parsedMessage.msg
294
152
  });
295
153
  }
296
154
  return compilerDiagnostics;
297
155
  }
156
+ function parseCompilerMessage(cwd, message) {
157
+ // regular error/warning - such as:
158
+ // C:\Users\aai\rmstudio\apmparts\dlo-pawn\stdlib\rm-dde.inc(392) : error 036: empty statement
159
+ // main.p(138) : warning 203: symbol is never used: "log_str"
160
+ // main.p(6) : fatal error 100: cannot read from file: "oTests/module_t"
161
+ const i0 = message.indexOf(' : ');
162
+ const i1 = message.indexOf(': ', i0 + 3);
163
+ const fileNameAndLineNumber = message.substring(0, i0).trim();
164
+ const levelAndCode = message.substring(i0 + 3, i1).trim();
165
+ const msg = message.substring(i1 + 2).trim();
166
+ // ignore lines which do not contain err/warn msg (or are empty)
167
+ if (!fileNameAndLineNumber || !levelAndCode || !msg) {
168
+ return null;
169
+ }
170
+ const [fileName, lineNumber] = fileNameAndLineNumber.split(/[()(-)]/);
171
+ const decodeLevelAndCode = levelAndCode.split(' ');
172
+ const level = decodeLevelAndCode[decodeLevelAndCode.length - 2]; //lvl is always the second last
173
+ const filePath = vscode_uri_1.Utils.joinPath(cwd, fileName);
174
+ let posixPath = filePath.fsPath.replace(/\\/g, '/');
175
+ if (posixPath.startsWith('/')) {
176
+ posixPath = posixPath.substring(1);
177
+ }
178
+ const patchedMessage = message.replace(fileName, posixPath);
179
+ return { level, msg, posixPath, lineNumber, message: patchedMessage };
180
+ }
298
181
  /**
299
182
  * Generates the DLO .cfg file for the dlo compiler
300
183
  * @param cwd
@@ -307,16 +190,17 @@ async function generateConfigFile(cwd, fs, manifest) {
307
190
  '-v2' // verbosity of stdout -> 0=quiet, 1=normal, 2=code/data/stack usage report
308
191
  ];
309
192
  const defaultIncPath = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.defaultInc);
310
- compileOptions.push(`-p${(0, CustomWasmFS_1.uriToMemFsPath)(defaultIncPath)}`);
193
+ compileOptions.push(`-p.${(0, CustomWasmFS_1.relativeMemFsPath)(cwd, defaultIncPath)}`);
311
194
  const dloLibs = await dependencies_1.Dependencies.getApmPartDependencies(cwd, fs, apm_1.APM.Part.dlo);
312
195
  for (const dloLib of dloLibs) {
313
196
  const dirName = vscode_uri_1.Utils.dirname(dloLib.path);
314
- compileOptions.push(`-i${(0, CustomWasmFS_1.uriToMemFsPath)(dirName)}`);
197
+ compileOptions.push(`-i.${(0, CustomWasmFS_1.relativeMemFsPath)(cwd, dirName)}`);
315
198
  }
316
199
  const dloConfiguration = manifest.dlo;
317
200
  if (dloConfiguration) {
318
201
  compileOptions.push(...dloConfiguration.compileOptions);
319
202
  }
203
+ compileOptions.push(`-o./dist/dlo/main.amx`);
320
204
  return {
321
205
  path: vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.cfg),
322
206
  data: compileOptions.join('\n')
package/out/main.js CHANGED
@@ -69,6 +69,23 @@ const optionStudioEnv = new commander_1.Option('-e, --env <environment>', 'CLI t
69
69
  * Generic option for the STUDIO_TOKEN
70
70
  */
71
71
  const optionStudioToken = new commander_1.Option('--token <API-token>', 'API Access Token (defaults to STUDIO_TOKEN environment variable)').default(process.env['STUDIO_TOKEN']);
72
+ /**
73
+ * Represents a command-line option for specifying the allowed backends deployment for a version.
74
+ *
75
+ * This variable represents an instance of an `Option` that determines which backends are permitted
76
+ * during the deployment process. The backends can be specified as*/
77
+ const optionAllowedBackends = new commander_1.Option('--allowedBackends <null|*|server.xz;server.yz>', 'specify the allowedBackends deployment for this version.').default(null);
78
+ const releasePhaseArguments = Object.values(apm_1.APM.TagPhase);
79
+ /**
80
+ * Represents a command-line option for specifying a release phase in a software deployment process.
81
+ *
82
+ * The option includes a flag `-ph` or `--phase`, followed by the user-defined release phase value. It offers predefined
83
+ * choices for acceptable release phase arguments, ensuring input validation. If no value is explicitly provided,
84
+ * the default release phase is set to 'release'.
85
+ */
86
+ const optionReleasePhase = new commander_1.Option('-ph --phase <release phase>', 'specify a release phase')
87
+ .choices(releasePhaseArguments)
88
+ .default('release');
72
89
  program
73
90
  .command('install')
74
91
  .aliases(['i'])
@@ -91,18 +108,27 @@ program
91
108
  const { env, token } = getDefaultOptions(opts);
92
109
  main((0, api_1.build)(cwd, cliFS_1.cliFS, logger, env, token, opts.part));
93
110
  });
94
- const releasePhaseArguments = Object.values(apm_1.APM.TagPhase);
95
111
  program
96
112
  .command('publish')
97
- .addOption(new commander_1.Option('-ph --phase <release phase>', 'specify a release phase')
98
- .choices(releasePhaseArguments)
99
- .default('release'))
100
- .addOption(new commander_1.Option('--allowedBackends <null|*|server.xz;server.yz>', 'specify the allowedBackends deployment for this version.').default(null))
113
+ .addOption(optionReleasePhase)
114
+ .addOption(optionAllowedBackends)
115
+ .addOption(optionStudioEnv)
116
+ .addOption(optionStudioToken)
117
+ .option('-i, --packagePath <path>', 'Publish the provided library or app package. Use "*" for autodetection.')
118
+ .action(async (opts) => {
119
+ const { env, token } = getDefaultOptions(opts);
120
+ main((0, api_1.publish)(cwd, cliFS_1.cliFS, logger, env, token, opts.allowedBackends, opts.phase, opts.packagePath));
121
+ });
122
+ program
123
+ .command('package')
124
+ .alias('pack')
125
+ .description('Package the project')
126
+ .addOption(optionReleasePhase)
101
127
  .addOption(optionStudioEnv)
102
128
  .addOption(optionStudioToken)
103
129
  .action(async (opts) => {
104
130
  const { env, token } = getDefaultOptions(opts);
105
- main((0, api_1.publish)(cwd, cliFS_1.cliFS, logger, env, token, opts.allowedBackends, opts.phase));
131
+ main((0, api_1.pack)(cwd, cliFS_1.cliFS, logger, env, token, opts.phase));
106
132
  });
107
133
  module.exports = function (argv) {
108
134
  program.parse(argv);
@@ -6,11 +6,10 @@ const helper_1 = require("../helper");
6
6
  var convertBlobToString = helper_1.Helper.convertBlobToString;
7
7
  const minimatch_1 = require("minimatch");
8
8
  const registryAPI_1 = require("../registryAPI");
9
- const manifest_1 = require("../manifest");
10
9
  const package_1 = require("./package");
11
10
  const globals_1 = require("../globals");
11
+ const tarjs_1 = require("@gera2ld/tarjs");
12
12
  const pako = require('pako');
13
- const tarball = require('tarballjs');
14
13
  const STUDIO_IGNORE_FILE = '.studioignore';
15
14
  //see original list: https://github.com/microsoft/vscode-vsce/blob/main/src/package.ts#L1603
16
15
  const defaultIgnore = [
@@ -57,13 +56,13 @@ var Library;
57
56
  * @param fs
58
57
  */
59
58
  async function createArchive(cwd, fs) {
60
- const tar = new tarball.TarWriter();
59
+ const tar = new tarjs_1.TarWriter();
61
60
  const filesToPack = await getFilesForArchive(cwd, fs);
62
61
  filesToPack.forEach(file => {
63
- tar.addFileArrayBuffer(file.name, file.data);
62
+ tar.addFile(file.name, file.data);
64
63
  });
65
64
  const tarBuffer = await tar.write();
66
- return pako.gzip(tarBuffer);
65
+ return pako.gzip(await tarBuffer.arrayBuffer());
67
66
  }
68
67
  Library.createArchive = createArchive;
69
68
  /**
@@ -102,13 +101,14 @@ var Library;
102
101
  * @param archive
103
102
  * @param env
104
103
  */
105
- async function publishPackage(cwd, fs, token, archive, env = globals_1.Globals.ENV.production) {
106
- const { publisher, name, version } = await manifest_1.Manifest.read(cwd, fs);
104
+ async function publishPackage(token, manifest, archive, env = globals_1.Globals.ENV.production) {
105
+ const { publisher, name, version } = manifest;
106
+ const extractedFiles = await package_1.Package.readFilesFromTarGz(archive, ['CHANGELOG.md', 'README.md', 'studio.json']);
107
107
  const files = {
108
- 'CHANGELOG.md': await package_1.Package.getChangelogFile(cwd, fs),
109
- 'README.md': await package_1.Package.getReadmeFile(cwd, fs, name),
110
- 'library.tar.gz': archive,
111
- 'studio.json': await manifest_1.Manifest.readAsBlob(cwd, fs)
108
+ 'CHANGELOG.md': await blobToUint8Array(extractedFiles['CHANGELOG.md']),
109
+ 'README.md': await blobToUint8Array(extractedFiles['README.md']),
110
+ 'studio.json': await blobToUint8Array(extractedFiles['studio.json']),
111
+ 'library.tar.gz': archive
112
112
  };
113
113
  return await registryAPI_1.Registry.publishLibraryVersion(token, publisher, name, version, files, env);
114
114
  }
@@ -159,4 +159,7 @@ async function getIgnoreFile(cwd, fs) {
159
159
  return '';
160
160
  }
161
161
  }
162
+ async function blobToUint8Array(blob) {
163
+ return new Uint8Array(await blob.arrayBuffer());
164
+ }
162
165
  //# sourceMappingURL=library.js.map
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Package = void 0;
4
+ exports.readManifestFromArchive = readManifestFromArchive;
4
5
  const vscode_uri_1 = require("vscode-uri");
5
6
  const helper_1 = require("../helper");
6
7
  const defaultFiles_1 = require("../defaultFiles");
@@ -14,6 +15,8 @@ const registryAPI_1 = require("../registryAPI");
14
15
  const manifest_1 = require("../manifest");
15
16
  const library_1 = require("./library");
16
17
  const dfiles_1 = require("../dfiles/dfiles");
18
+ const tarjs_1 = require("@gera2ld/tarjs");
19
+ const pako = require('pako');
17
20
  var Package;
18
21
  (function (Package) {
19
22
  class BuildError extends Error {
@@ -114,6 +117,29 @@ var Package;
114
117
  }
115
118
  }
116
119
  Package.release = release;
120
+ async function pack(cwd, fs, logger, env, token, releasePhase) {
121
+ const manifest = await manifest_1.Manifest.read(cwd, fs);
122
+ const archiveName = `${manifest.name}-${manifest.version}.tar.gz`;
123
+ let archive = null;
124
+ if (manifest_1.Manifest.isLibrary(manifest)) {
125
+ logger.info('Library project detected. Packing library...');
126
+ archive = await createLibraryPackage(cwd, fs, logger, token, env);
127
+ }
128
+ else {
129
+ logger.info('App project detected. Packing app...');
130
+ const apmTag = await createAPMPackage(cwd, fs, logger, token, releasePhase, env);
131
+ archive = await createArchiveFromApmPackage(apmTag);
132
+ }
133
+ const archivePath = vscode_uri_1.Utils.joinPath(cwd, archiveName);
134
+ if (archive !== null) {
135
+ await fs.writeFile(archivePath, archive);
136
+ logger.done(`Packaged: ${archivePath.fsPath}`);
137
+ }
138
+ else {
139
+ logger.error(`Could not create archive: ${archivePath.fsPath}`);
140
+ }
141
+ }
142
+ Package.pack = pack;
117
143
  /**
118
144
  * Publish an application model tag
119
145
  * @param cwd
@@ -125,19 +151,13 @@ var Package;
125
151
  * @param env
126
152
  */
127
153
  async function releaseAPM(cwd, fs, logger, token, releasePhase, allowedBackends = null, env) {
128
- if (!Object.values(apm_1.APM.TagPhase).includes(releasePhase)) {
129
- throw new Error(`ReleasePhase: ${releasePhase} is not a valid release phase`);
130
- }
131
- await manifest_1.Manifest.validateBasicManifest(cwd, fs, null);
132
154
  const application = await apm_1.APM.validateAccess(cwd, fs, token, false, env);
133
155
  if (!application) {
134
- return;
156
+ throw new Error('Could not validate access to application');
135
157
  }
136
- // build the complete project
137
- await buildAll(cwd, fs, logger, env, token);
158
+ const tagContent = await createAPMPackage(cwd, fs, logger, token, releasePhase, env);
138
159
  // update the store apm with the actual name/description/...
139
160
  await apm_1.APM.updateProfile(cwd, fs, token, env);
140
- const tagContent = await apm_1.APM.createTag(cwd, fs, releasePhase);
141
161
  const newTag = await apm_1.APM.publishTag(cwd, fs, token, tagContent, env);
142
162
  if (allowedBackends !== null) {
143
163
  const manifest = await manifest_1.Manifest.read(cwd, fs);
@@ -160,15 +180,55 @@ var Package;
160
180
  */
161
181
  async function releaseLibrary(cwd, fs, logger, token, env) {
162
182
  const manifest = await manifest_1.Manifest.read(cwd, fs);
163
- await manifest_1.Manifest.validateBasicManifest(cwd, fs, manifest);
164
- await validatePublishSettings(cwd, fs, token, env);
165
- // build the complete project
166
- await buildAll(cwd, fs, logger, env, token);
167
- const archive = await library_1.Library.createArchive(cwd, fs);
168
- await library_1.Library.publishPackage(cwd, fs, token, archive, env);
183
+ const archive = await createLibraryPackage(cwd, fs, logger, token, env);
184
+ await library_1.Library.publishPackage(token, manifest, archive, env);
169
185
  logger.done(`Library "${manifest.publisher}/${manifest.name}" with version "${manifest.version}" published!`);
170
186
  }
171
187
  Package.releaseLibrary = releaseLibrary;
188
+ /**
189
+ * Publishes an archive package to the appropriate library or application registry.
190
+ *
191
+ * @param {URI} cwd - The current working directory where the package archive is located.
192
+ * @param {LocalFS} fs - The file system interface for reading and writing files.
193
+ * @param {Log.Logger} logger - The logger instance for logging messages during the operation.
194
+ * @param {Registry.AuthToken} token - The authorization token required for interacting with the registry.
195
+ * @param {Globals.ENV} env - The global environment settings.
196
+ * @param {string} packagePath - The relative path to the archive package to be published.
197
+ * @param {APM.TagPhase} [releasePhase] - An optional release phase for tagging the published version of the application.
198
+ * @param {Registry.ApiNewApplication['allowedBackends']} [allowedBackends] - An optional list of allowed backends for the published version.
199
+ *
200
+ * @return {Promise<void>} A promise that resolves when the publication process completes successfully.
201
+ */
202
+ async function publishArchive(cwd, fs, logger, token, env, packagePath, releasePhase, allowedBackends = null) {
203
+ if (packagePath === '*') {
204
+ const localManifest = await manifest_1.Manifest.read(cwd, fs);
205
+ packagePath = `${localManifest.name}-${localManifest.version}.tar.gz`;
206
+ logger.info(`Publishing detected archive package "${packagePath}"...`);
207
+ }
208
+ const archivePath = vscode_uri_1.Utils.joinPath(cwd, packagePath);
209
+ if (!(await fs.stat(archivePath))) {
210
+ throw new Error(`Archive package not found: ${archivePath.fsPath}`);
211
+ }
212
+ const archive = await fs.readFile(archivePath);
213
+ const manifest = await readManifestFromArchive(archive);
214
+ const { publisher, registry, version } = manifest;
215
+ // add library publishing.
216
+ if (manifest_1.Manifest.isLibrary(manifest)) {
217
+ await library_1.Library.publishPackage(token, manifest, archive, env);
218
+ logger.done(`Library "${publisher}/${manifest.name}" with version "${manifest.version}" published!`);
219
+ }
220
+ else {
221
+ await registryAPI_1.Registry.updateApplicationFile(token, publisher, registry.id, version, 'app.tar.gz', archive, env);
222
+ // update the version profile
223
+ await registryAPI_1.Registry.updateExistingApplicationVersion(token, publisher, registry?.id, version, {
224
+ allowedBackends: allowedBackends || undefined,
225
+ phase: releasePhase || undefined
226
+ }, env);
227
+ logger.info(`Tag "${version}" with phase "${releasePhase}" shared with ${[...(allowedBackends || '')].join(';')}!`);
228
+ logger.done(`Tag "${version}" with phase "${releasePhase}" published!`);
229
+ }
230
+ }
231
+ Package.publishArchive = publishArchive;
172
232
  /**
173
233
  * Read the projects README.md file
174
234
  * validates if the file content is the initial content
@@ -247,6 +307,22 @@ var Package;
247
307
  }
248
308
  }
249
309
  Package.validatePublishSettings = validatePublishSettings;
310
+ async function readFilesFromTarGz(gzipped, fileNames) {
311
+ // Decompress GZ
312
+ const tarData = pako.ungzip(gzipped);
313
+ // Parse TAR with tarballjs
314
+ const tarReader = await tarjs_1.TarReader.load(tarData);
315
+ const fileList = {};
316
+ for (const entry of tarReader.fileInfos) {
317
+ if (fileNames.includes(entry.name)) {
318
+ // Return file contents as a Buffer
319
+ fileList[entry.name] = tarReader.getFileBlob(entry.name);
320
+ }
321
+ }
322
+ // File not found
323
+ return fileList;
324
+ }
325
+ Package.readFilesFromTarGz = readFilesFromTarGz;
250
326
  })(Package || (exports.Package = Package = {}));
251
327
  /**
252
328
  * Normalize the selected parts parameter for building.
@@ -357,4 +433,57 @@ function logDiagnostics(logger, diagnostics) {
357
433
  }
358
434
  });
359
435
  }
436
+ async function createLibraryPackage(cwd, fs, logger, token, env) {
437
+ const manifest = await manifest_1.Manifest.read(cwd, fs);
438
+ await manifest_1.Manifest.validateBasicManifest(cwd, fs, manifest);
439
+ // build the complete project
440
+ await Package.buildAll(cwd, fs, logger, env, token);
441
+ return await library_1.Library.createArchive(cwd, fs);
442
+ }
443
+ async function createAPMPackage(cwd, fs, logger, token, releasePhase, env) {
444
+ if (!Object.values(apm_1.APM.TagPhase).includes(releasePhase)) {
445
+ throw new Error(`ReleasePhase: ${releasePhase} is not a valid release phase`);
446
+ }
447
+ await manifest_1.Manifest.validateBasicManifest(cwd, fs, null);
448
+ // build the complete project
449
+ await Package.buildAll(cwd, fs, logger, env, token);
450
+ return await apm_1.APM.createTag(cwd, fs, releasePhase);
451
+ }
452
+ async function createArchiveFromApmPackage(data) {
453
+ const tar = new tarjs_1.TarWriter();
454
+ // @ts-ignore .entries is valid on FormData
455
+ for (const [name, value] of data.entries()) {
456
+ if (name === 'tag') {
457
+ const fileNode = value;
458
+ tar.addFile(name, fileNode);
459
+ }
460
+ else {
461
+ const fileNode = value;
462
+ tar.addFile(name, await fileNode.arrayBuffer());
463
+ }
464
+ }
465
+ const tarBuffer = await tar.write();
466
+ return pako.gzip(await tarBuffer.arrayBuffer());
467
+ }
468
+ async function readManifestFromArchive(archive) {
469
+ const manifestData = await readFileFromTarGz(archive, ['studio.json', 'src/studio.json']);
470
+ if (!manifestData) {
471
+ throw new Error(`Could not find "studio.json" in archive`);
472
+ }
473
+ return JSON.parse(await manifestData.text());
474
+ }
475
+ async function readFileFromTarGz(gzipped, possibleFilenames) {
476
+ // Decompress GZ
477
+ const tarData = pako.ungzip(gzipped);
478
+ // Parse TAR with tarballjs
479
+ const tarReader = await tarjs_1.TarReader.load(tarData);
480
+ for (const entry of tarReader.fileInfos) {
481
+ if (possibleFilenames.includes(entry.name)) {
482
+ // Return file contents as a Buffer
483
+ return tarReader.getFileBlob(entry.name);
484
+ }
485
+ }
486
+ // File not found
487
+ return null;
488
+ }
360
489
  //# sourceMappingURL=package.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microtronics/studio-cli",
3
- "version": "0.29.4",
3
+ "version": "0.31.0",
4
4
  "description": "Microtronics Studio CLI Tool",
5
5
  "main": "./out/api.js",
6
6
  "typings": "./dist/studio-cli.d.ts",
@@ -41,7 +41,7 @@
41
41
  "openapi-fetch": "^0.13.0",
42
42
  "pako": "^2.1.0",
43
43
  "semver": "^7.6.3",
44
- "tarballjs": "github:ankitrohatgi/tarballjs",
44
+ "@gera2ld/tarjs": "^0.3.1",
45
45
  "tinytar-fix": "^0.1.1",
46
46
  "update-notifier": "^7.3.1",
47
47
  "vscode-uri": "^3.0.8",
@@ -63,9 +63,11 @@
63
63
  "chai": "^4.3.8",
64
64
  "chai-as-promised": "^7.1.2",
65
65
  "cross-env": "^7.0.3",
66
+ "extract-zip": "^2.0.1",
66
67
  "mocha": "^10.8.2",
67
68
  "mocha-junit-reporter": "^2.2.1",
68
69
  "openapi-typescript": "^7.6.0",
70
+ "tar": "^7.4.3",
69
71
  "ts-node": "^10.9.2",
70
72
  "typescript": "^5.6.3"
71
73
  },