@putdotio/taizn 1.3.0 → 1.4.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/README.md CHANGED
@@ -46,6 +46,8 @@ Project files:
46
46
 
47
47
  ```bash
48
48
  taizn check
49
+ taizn apps
50
+ taizn apps put
49
51
  taizn profile
50
52
  taizn package
51
53
  taizn install
@@ -58,7 +60,8 @@ taizn --version
58
60
  ```
59
61
 
60
62
  `check` verifies the configured Tizen CLI and `sdb`, then prints connected
61
- targets without requiring `taizn.json`. `profile` imports
63
+ targets without requiring `taizn.json`. `apps` lists installed applications on
64
+ the target, with an optional query filter. `profile` imports
62
65
  `.taizn/certificates/author.p12` and
63
66
  `.taizn/certificates/distributor.p12` into a Tizen security profile.
64
67
  `package` builds and signs a `.wgt`. `install` packages and sideloads it.
package/dist/taizn.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { NodeRuntime, NodeServices } from "@effect/platform-node";
3
3
  import { Argument, CliError, Command, Flag } from "effect/unstable/cli";
4
- import { Console, Context, Effect, FileSystem, Layer, Schema, Stream } from "effect";
4
+ import { Console, Context, Effect, FileSystem, Layer, Option, Schema, Stream } from "effect";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import { homedir } from "node:os";
7
7
  import { existsSync } from "node:fs";
@@ -80,6 +80,11 @@ var MultipleTargetsConnected = class extends Schema.TaggedErrorClass()("Multiple
80
80
  return `Multiple Tizen targets are connected: ${this.targets.join(", ")}. Set TAIZN_TARGET explicitly.`;
81
81
  }
82
82
  };
83
+ var MissingTizenTarget = class extends Schema.TaggedErrorClass()("MissingTizenTarget", {}) {
84
+ get message() {
85
+ return "No Tizen target is connected. Set TAIZN_TARGET or connect exactly one device.";
86
+ }
87
+ };
83
88
  var MissingTvRemoteHost = class extends Schema.TaggedErrorClass()("MissingTvRemoteHost", {}) {
84
89
  get message() {
85
90
  return "Samsung TV host is required. Set TAIZN_TV_HOST or TAIZN_TARGET.";
@@ -793,6 +798,28 @@ const runWidget = Effect.fn("runWidget")(function* ({ config, env }) {
793
798
  ], { env: yield* baseChildEnv() });
794
799
  yield* Console.log(`Launched ${variant.applicationId}`);
795
800
  });
801
+ const listInstalledApplications = Effect.fn("listInstalledApplications")(function* (env, query) {
802
+ const sdbPath = yield* resolveSdb(env);
803
+ if (env.target) yield* run$1(sdbPath, ["connect", env.target], { env: yield* baseChildEnv() });
804
+ const target = yield* resolveRequiredSdbTarget(env, sdbPath);
805
+ const output = yield* capture(sdbPath, [
806
+ "-s",
807
+ target,
808
+ "shell",
809
+ "0",
810
+ "applist"
811
+ ]);
812
+ const queryLabel = query?.trim();
813
+ const normalizedQuery = normalizeQuery(queryLabel);
814
+ const applications = parseInstalledApplications(output).filter((application) => matchesApplicationQuery(application, normalizedQuery));
815
+ const suffix = queryLabel ? ` matching "${queryLabel}"` : "";
816
+ yield* Console.log(`Installed Tizen applications${suffix} on ${target}:`);
817
+ if (applications.length === 0) {
818
+ yield* Console.log("none");
819
+ return;
820
+ }
821
+ for (const application of applications) yield* Console.log(`- ${application.name} (${application.applicationId})`);
822
+ });
796
823
  const resolveTizenCli = Effect.fn("resolveTizenCli")(function* (env) {
797
824
  return yield* requireFile(env.tizenCli ?? (yield* defaultTizenCli()), "Tizen CLI");
798
825
  });
@@ -971,6 +998,30 @@ const resolveRunTarget = Effect.fn("resolveRunTarget")(function* (env, sdbPath)
971
998
  }
972
999
  if (devices.length > 1) return yield* MultipleTargetsConnected.make({ targets: devices.map((device) => device.id) });
973
1000
  });
1001
+ const resolveRequiredSdbTarget = Effect.fn("resolveRequiredSdbTarget")(function* (env, sdbPath) {
1002
+ if (env.target) return env.target;
1003
+ const devices = yield* listSdbDevices(sdbPath);
1004
+ if (devices.length === 1) {
1005
+ const device = devices[0];
1006
+ if (device) {
1007
+ yield* Console.log(`Using connected Tizen target: ${device.id}${device.label ? ` (${device.label})` : ""}`);
1008
+ return device.id;
1009
+ }
1010
+ }
1011
+ if (devices.length > 1) return yield* MultipleTargetsConnected.make({ targets: devices.map((device) => device.id) });
1012
+ return yield* MissingTizenTarget.make({});
1013
+ });
1014
+ const parseInstalledApplications = (output) => output.split("\n").flatMap((line) => {
1015
+ const match = line.match(/^\s*'([^']*)'\s+'([^']*)'\s*$/);
1016
+ const name = match?.[1]?.trim();
1017
+ const applicationId = match?.[2]?.trim();
1018
+ return name && applicationId ? [{
1019
+ applicationId,
1020
+ name
1021
+ }] : [];
1022
+ });
1023
+ const normalizeQuery = (query) => query?.trim().toLowerCase();
1024
+ const matchesApplicationQuery = (application, normalizedQuery) => !normalizedQuery || application.name.toLowerCase().includes(normalizedQuery) || application.applicationId.toLowerCase().includes(normalizedQuery);
974
1025
  const run$1 = Effect.fn("run")(function* (command, args, options) {
975
1026
  const paths = yield* getPaths();
976
1027
  const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
@@ -1028,6 +1079,9 @@ const taizn = Command.make("taizn", {}, () => withContext((context) => packageWi
1028
1079
  const check = Command.make("check", {}, () => Effect.gen(function* () {
1029
1080
  yield* checkTizen(yield* loadEnv());
1030
1081
  }));
1082
+ const apps = Command.make("apps", { query: Argument.string("query").pipe(Argument.optional) }, ({ query }) => Effect.gen(function* () {
1083
+ yield* listInstalledApplications(yield* loadEnv(), Option.getOrUndefined(query));
1084
+ }));
1031
1085
  const profile = Command.make("profile", {}, () => withContext((context) => createProfile(context)));
1032
1086
  const pack = Command.make("package", {}, () => withContext((context) => packageWidget(context).pipe(Effect.asVoid)));
1033
1087
  const install = Command.make("install", {}, () => withContext((context) => installWidget(context)));
@@ -1050,6 +1104,7 @@ const tv = Command.make("tv", {}).pipe(Command.withSubcommands([
1050
1104
  tvInfo
1051
1105
  ]));
1052
1106
  const command = taizn.pipe(Command.withSubcommands([
1107
+ apps,
1053
1108
  check,
1054
1109
  profile,
1055
1110
  pack,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@putdotio/taizn",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "A tiny CLI companion for interacting with Tizen ecosystem.",
5
5
  "keywords": [
6
6
  "cli",