@microtronics/studio-cli 0.30.0 → 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,18 +1,28 @@
1
1
 
2
2
 
3
- ## 0.30.0 (2025-05-05)
3
+ ## 0.31.0 (2025-05-05)
4
4
 
5
5
 
6
6
  ### Features
7
7
 
8
- * **studio-cli:** add support for packaging app projects ([280115f](https://bitbucket.org/microtronics-core/vscode-studio/commits/280115fa77afb78754884a4eb83bd0365ff5b319))
9
- * **studio-cli:** add support for packaging library projects ([1888df1](https://bitbucket.org/microtronics-core/vscode-studio/commits/1888df1b5d8c2f53a9705756d28d42360109e3ba))
10
-
11
-
12
- ### Bug Fixes
13
-
14
- * **studio-cli:** ensure dist/dlo directory is created on compile ([f110636](https://bitbucket.org/microtronics-core/vscode-studio/commits/f110636fc5042a5e25cc2d26fc98df4356d706bb))
15
- * **studio-cli:** rename method in CustomWasmFS ([c3e1a22](https://bitbucket.org/microtronics-core/vscode-studio/commits/c3e1a227d7e57e91f9ddea45f11412ed59f71614))
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))
16
26
  * **studio-cli:** run dlo compiler relative to the cwd ([110b476](https://bitbucket.org/microtronics-core/vscode-studio/commits/110b4767bda8134aca2781c51f6e06bf800c4c67))
17
27
 
18
28
  ## 0.29.4 (2025-04-25)
@@ -2070,7 +2070,7 @@ export declare namespace Library {
2070
2070
  * @param archive
2071
2071
  * @param env
2072
2072
  */
2073
- 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>;
2074
2074
  }
2075
2075
 
2076
2076
  declare interface LocalFS {
@@ -2359,6 +2359,21 @@ export declare namespace Package {
2359
2359
  * @param env
2360
2360
  */
2361
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>;
2362
2377
  /**
2363
2378
  * Read the projects README.md file
2364
2379
  * validates if the file content is the initial content
@@ -2382,6 +2397,9 @@ export declare namespace Package {
2382
2397
  * @param env
2383
2398
  */
2384
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
+ }>;
2385
2403
  }
2386
2404
 
2387
2405
  declare function parseWarningsAndErrors(cwd: URI, stderr: string[], relatedFile?: URI): Diagnostics.File[];
@@ -4603,9 +4621,10 @@ declare interface paths {
4603
4621
  * @param {string | null} apiToken - The API token for authentication, or null if not applicable.
4604
4622
  * @param {string | undefined} optsAllowedBackends - A semicolon-separated list of allowed backends, or '*' to allow all, or undefined if not specified.
4605
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.
4606
4625
  * @return {Promise<void>} A promise that resolves when the package has been successfully published or rejects with an error if the process fails.
4607
4626
  */
4608
- 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>;
4609
4628
 
4610
4629
  export declare namespace Registry {
4611
4630
  export type AuthToken = string | null;
package/out/api.js CHANGED
@@ -110,13 +110,19 @@ async function parseAllowedBackends(optsAllowedBackends) {
110
110
  * @param {string | null} apiToken - The API token for authentication, or null if not applicable.
111
111
  * @param {string | undefined} optsAllowedBackends - A semicolon-separated list of allowed backends, or '*' to allow all, or undefined if not specified.
112
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.
113
114
  * @return {Promise<void>} A promise that resolves when the package has been successfully published or rejects with an error if the process fails.
114
115
  */
115
- async function publish(cwd, fs, logger, env, apiToken, optsAllowedBackends, optsPhase) {
116
+ async function publish(cwd, fs, logger, env, apiToken, optsAllowedBackends, optsPhase, packagePath) {
116
117
  logger.info('Publishing package...');
117
118
  const allowedBackends = await parseAllowedBackends(optsAllowedBackends);
118
- await package_1.Package.validatePublishSettings(cwd, fs, apiToken, env);
119
- return package_1.Package.release(cwd, fs, logger, env, apiToken, optsPhase, allowedBackends);
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);
125
+ }
120
126
  }
121
127
  /**
122
128
  * Packs the given directory into a deployable package using the specified configuration.
package/out/main.js CHANGED
@@ -114,9 +114,10 @@ program
114
114
  .addOption(optionAllowedBackends)
115
115
  .addOption(optionStudioEnv)
116
116
  .addOption(optionStudioToken)
117
+ .option('-i, --packagePath <path>', 'Publish the provided library or app package. Use "*" for autodetection.')
117
118
  .action(async (opts) => {
118
119
  const { env, token } = getDefaultOptions(opts);
119
- main((0, api_1.publish)(cwd, cliFS_1.cliFS, logger, env, token, opts.allowedBackends, opts.phase));
120
+ main((0, api_1.publish)(cwd, cliFS_1.cliFS, logger, env, token, opts.allowedBackends, opts.phase, opts.packagePath));
120
121
  });
121
122
  program
122
123
  .command('package')
@@ -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,8 +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");
17
19
  const pako = require('pako');
18
- const tarball = require('tarballjs');
19
20
  var Package;
20
21
  (function (Package) {
21
22
  class BuildError extends Error {
@@ -180,10 +181,54 @@ var Package;
180
181
  async function releaseLibrary(cwd, fs, logger, token, env) {
181
182
  const manifest = await manifest_1.Manifest.read(cwd, fs);
182
183
  const archive = await createLibraryPackage(cwd, fs, logger, token, env);
183
- await library_1.Library.publishPackage(cwd, fs, token, archive, env);
184
+ await library_1.Library.publishPackage(token, manifest, archive, env);
184
185
  logger.done(`Library "${manifest.publisher}/${manifest.name}" with version "${manifest.version}" published!`);
185
186
  }
186
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;
187
232
  /**
188
233
  * Read the projects README.md file
189
234
  * validates if the file content is the initial content
@@ -262,6 +307,22 @@ var Package;
262
307
  }
263
308
  }
264
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;
265
326
  })(Package || (exports.Package = Package = {}));
266
327
  /**
267
328
  * Normalize the selected parts parameter for building.
@@ -389,19 +450,40 @@ async function createAPMPackage(cwd, fs, logger, token, releasePhase, env) {
389
450
  return await apm_1.APM.createTag(cwd, fs, releasePhase);
390
451
  }
391
452
  async function createArchiveFromApmPackage(data) {
392
- const tar = new tarball.TarWriter();
453
+ const tar = new tarjs_1.TarWriter();
393
454
  // @ts-ignore .entries is valid on FormData
394
455
  for (const [name, value] of data.entries()) {
395
456
  if (name === 'tag') {
396
457
  const fileNode = value;
397
- tar.addTextFile(name, fileNode);
458
+ tar.addFile(name, fileNode);
398
459
  }
399
460
  else {
400
461
  const fileNode = value;
401
- tar.addFileArrayBuffer(name, await fileNode.arrayBuffer());
462
+ tar.addFile(name, await fileNode.arrayBuffer());
402
463
  }
403
464
  }
404
465
  const tarBuffer = await tar.write();
405
- return pako.gzip(tarBuffer);
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;
406
488
  }
407
489
  //# sourceMappingURL=package.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microtronics/studio-cli",
3
- "version": "0.30.0",
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",