@table-js/platform 0.0.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/README.md +31 -0
- package/dist/cli.mjs +357 -0
- package/dist/index.d.mts +50 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.js +372 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +332 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# @tablejs/platform
|
|
2
|
+
|
|
3
|
+
Build tools and platform adapters for Table.js.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -D @tablejs/platform
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Build for all platforms
|
|
15
|
+
table build --platform all
|
|
16
|
+
|
|
17
|
+
# Build for specific platform
|
|
18
|
+
table build --platform tizen
|
|
19
|
+
table build --platform webos
|
|
20
|
+
table build --platform android
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Supported Platforms
|
|
24
|
+
|
|
25
|
+
- **Tizen** - Samsung Smart TV (.wgt)
|
|
26
|
+
- **webOS** - LG Smart TV (.ipk)
|
|
27
|
+
- **Android TV** - Android TV (.apk)
|
|
28
|
+
|
|
29
|
+
## License
|
|
30
|
+
|
|
31
|
+
MIT
|
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/cli.ts
|
|
4
|
+
import { Command } from "commander";
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import ora from "ora";
|
|
7
|
+
|
|
8
|
+
// src/builder.ts
|
|
9
|
+
import { build as viteBuild } from "vite";
|
|
10
|
+
|
|
11
|
+
// src/adapters/tizen.ts
|
|
12
|
+
import path from "path";
|
|
13
|
+
import fs from "fs-extra";
|
|
14
|
+
import archiver from "archiver";
|
|
15
|
+
import { createWriteStream } from "fs";
|
|
16
|
+
var TizenAdapter = class {
|
|
17
|
+
name = "Tizen (Samsung)";
|
|
18
|
+
async build(options) {
|
|
19
|
+
const distDir = `${options.outDir}/tizen`;
|
|
20
|
+
await this.createConfig(distDir);
|
|
21
|
+
}
|
|
22
|
+
async package(distDir) {
|
|
23
|
+
const outputPath = path.join(distDir, "..", "app.wgt");
|
|
24
|
+
await new Promise((resolve, reject) => {
|
|
25
|
+
const output = createWriteStream(outputPath);
|
|
26
|
+
const archive = archiver("zip", { zlib: { level: 9 } });
|
|
27
|
+
output.on("close", () => resolve());
|
|
28
|
+
archive.on("error", reject);
|
|
29
|
+
archive.pipe(output);
|
|
30
|
+
archive.directory(distDir, false);
|
|
31
|
+
archive.finalize();
|
|
32
|
+
});
|
|
33
|
+
return outputPath;
|
|
34
|
+
}
|
|
35
|
+
async createConfig(distDir) {
|
|
36
|
+
const pkg = await this.readPackageJson();
|
|
37
|
+
const config = `<?xml version="1.0" encoding="UTF-8"?>
|
|
38
|
+
<widget xmlns="http://www.w3.org/ns/widgets"
|
|
39
|
+
xmlns:tizen="http://tizen.org/ns/widgets"
|
|
40
|
+
id="${pkg.id || "com.example.app"}"
|
|
41
|
+
version="${pkg.version}"
|
|
42
|
+
viewmodes="maximized">
|
|
43
|
+
<tizen:application id="${pkg.id || "com.example.app"}.App"
|
|
44
|
+
package="${pkg.id || "com.example.app"}"
|
|
45
|
+
required_version="6.0"/>
|
|
46
|
+
<content src="index.html"/>
|
|
47
|
+
<feature name="http://tizen.org/feature/screen.size.all"/>
|
|
48
|
+
<icon src="icon.png"/>
|
|
49
|
+
<name>${pkg.name}</name>
|
|
50
|
+
<tizen:profile name="tv"/>
|
|
51
|
+
<tizen:setting screen-orientation="landscape"
|
|
52
|
+
context-menu="disable"
|
|
53
|
+
background-support="disable"
|
|
54
|
+
encryption="disable"
|
|
55
|
+
install-location="auto"/>
|
|
56
|
+
</widget>`;
|
|
57
|
+
await fs.writeFile(path.join(distDir, "config.xml"), config);
|
|
58
|
+
}
|
|
59
|
+
async readPackageJson() {
|
|
60
|
+
try {
|
|
61
|
+
const pkg = await fs.readJson("package.json");
|
|
62
|
+
return {
|
|
63
|
+
id: pkg.tizenAppId || pkg.name,
|
|
64
|
+
name: pkg.name,
|
|
65
|
+
version: pkg.version,
|
|
66
|
+
description: pkg.description
|
|
67
|
+
};
|
|
68
|
+
} catch {
|
|
69
|
+
return {
|
|
70
|
+
id: "com.example.app",
|
|
71
|
+
name: "Table App",
|
|
72
|
+
version: "1.0.0"
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// src/adapters/webos.ts
|
|
79
|
+
import path2 from "path";
|
|
80
|
+
import fs2 from "fs-extra";
|
|
81
|
+
import archiver2 from "archiver";
|
|
82
|
+
import { createWriteStream as createWriteStream2 } from "fs";
|
|
83
|
+
var WebOSAdapter = class {
|
|
84
|
+
name = "webOS (LG)";
|
|
85
|
+
async build(options) {
|
|
86
|
+
const distDir = `${options.outDir}/webos`;
|
|
87
|
+
await this.createAppInfo(distDir);
|
|
88
|
+
}
|
|
89
|
+
async package(distDir) {
|
|
90
|
+
const outputPath = path2.join(distDir, "..", "app.ipk");
|
|
91
|
+
await new Promise((resolve, reject) => {
|
|
92
|
+
const output = createWriteStream2(outputPath);
|
|
93
|
+
const archive = archiver2("tar", { gzip: true });
|
|
94
|
+
output.on("close", () => resolve());
|
|
95
|
+
archive.on("error", reject);
|
|
96
|
+
archive.pipe(output);
|
|
97
|
+
archive.directory(distDir, false);
|
|
98
|
+
archive.finalize();
|
|
99
|
+
});
|
|
100
|
+
return outputPath;
|
|
101
|
+
}
|
|
102
|
+
async createAppInfo(distDir) {
|
|
103
|
+
const pkg = await this.readPackageJson();
|
|
104
|
+
const appInfo = {
|
|
105
|
+
id: pkg.id || "com.example.app",
|
|
106
|
+
version: pkg.version,
|
|
107
|
+
vendor: "Table.js",
|
|
108
|
+
type: "web",
|
|
109
|
+
main: "index.html",
|
|
110
|
+
title: pkg.name,
|
|
111
|
+
icon: "icon.png",
|
|
112
|
+
largeIcon: "icon.png",
|
|
113
|
+
bgImage: "splash.png",
|
|
114
|
+
resolution: "1920x1080",
|
|
115
|
+
disallowScrollingInMainWindow: true
|
|
116
|
+
};
|
|
117
|
+
await fs2.writeJson(path2.join(distDir, "appinfo.json"), appInfo, { spaces: 2 });
|
|
118
|
+
}
|
|
119
|
+
async readPackageJson() {
|
|
120
|
+
try {
|
|
121
|
+
const pkg = await fs2.readJson("package.json");
|
|
122
|
+
return {
|
|
123
|
+
id: pkg.webosAppId || pkg.name,
|
|
124
|
+
name: pkg.name,
|
|
125
|
+
version: pkg.version,
|
|
126
|
+
description: pkg.description
|
|
127
|
+
};
|
|
128
|
+
} catch {
|
|
129
|
+
return {
|
|
130
|
+
id: "com.example.app",
|
|
131
|
+
name: "Table App",
|
|
132
|
+
version: "1.0.0"
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// src/adapters/android.ts
|
|
139
|
+
import path3 from "path";
|
|
140
|
+
import fs3 from "fs-extra";
|
|
141
|
+
import { execa } from "execa";
|
|
142
|
+
var AndroidAdapter = class {
|
|
143
|
+
name = "Android TV";
|
|
144
|
+
async build(options) {
|
|
145
|
+
const distDir = `${options.outDir}/android`;
|
|
146
|
+
await this.createWebViewProject(distDir);
|
|
147
|
+
}
|
|
148
|
+
async package(distDir) {
|
|
149
|
+
const projectDir = path3.join(distDir, "android-project");
|
|
150
|
+
try {
|
|
151
|
+
await execa("./gradlew", ["assembleRelease"], {
|
|
152
|
+
cwd: projectDir,
|
|
153
|
+
stdio: "inherit"
|
|
154
|
+
});
|
|
155
|
+
const apkPath = path3.join(projectDir, "app/build/outputs/apk/release/app-release.apk");
|
|
156
|
+
const outputPath = path3.join(distDir, "..", "app.apk");
|
|
157
|
+
await fs3.copy(apkPath, outputPath);
|
|
158
|
+
return outputPath;
|
|
159
|
+
} catch (error) {
|
|
160
|
+
throw new Error("Android build failed. Make sure Android SDK is installed.");
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
async createWebViewProject(distDir) {
|
|
164
|
+
const pkg = await this.readPackageJson();
|
|
165
|
+
const projectDir = path3.join(distDir, "android-project");
|
|
166
|
+
await fs3.ensureDir(projectDir);
|
|
167
|
+
await fs3.copy(distDir, path3.join(projectDir, "app/src/main/assets/www"));
|
|
168
|
+
await this.createManifest(projectDir, pkg);
|
|
169
|
+
await this.createGradleFiles(projectDir, pkg);
|
|
170
|
+
await this.createMainActivity(projectDir, pkg);
|
|
171
|
+
}
|
|
172
|
+
async createManifest(projectDir, pkg) {
|
|
173
|
+
const manifest = `<?xml version="1.0" encoding="utf-8"?>
|
|
174
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
175
|
+
package="${pkg.id || "com.example.app"}">
|
|
176
|
+
|
|
177
|
+
<uses-permission android:name="android.permission.INTERNET" />
|
|
178
|
+
<uses-feature android:name="android.software.leanback" android:required="true" />
|
|
179
|
+
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
|
|
180
|
+
|
|
181
|
+
<application
|
|
182
|
+
android:allowBackup="true"
|
|
183
|
+
android:icon="@mipmap/ic_launcher"
|
|
184
|
+
android:label="${pkg.name}"
|
|
185
|
+
android:banner="@drawable/banner"
|
|
186
|
+
android:theme="@style/Theme.Leanback">
|
|
187
|
+
|
|
188
|
+
<activity
|
|
189
|
+
android:name=".MainActivity"
|
|
190
|
+
android:exported="true"
|
|
191
|
+
android:screenOrientation="landscape">
|
|
192
|
+
<intent-filter>
|
|
193
|
+
<action android:name="android.intent.action.MAIN" />
|
|
194
|
+
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
|
|
195
|
+
</intent-filter>
|
|
196
|
+
</activity>
|
|
197
|
+
</application>
|
|
198
|
+
</manifest>`;
|
|
199
|
+
const manifestPath = path3.join(projectDir, "app/src/main/AndroidManifest.xml");
|
|
200
|
+
await fs3.ensureDir(path3.dirname(manifestPath));
|
|
201
|
+
await fs3.writeFile(manifestPath, manifest);
|
|
202
|
+
}
|
|
203
|
+
async createGradleFiles(projectDir, pkg) {
|
|
204
|
+
const buildGradle = `plugins {
|
|
205
|
+
id 'com.android.application'
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
android {
|
|
209
|
+
namespace '${pkg.id || "com.example.app"}'
|
|
210
|
+
compileSdk 34
|
|
211
|
+
|
|
212
|
+
defaultConfig {
|
|
213
|
+
applicationId "${pkg.id || "com.example.app"}"
|
|
214
|
+
minSdk 21
|
|
215
|
+
targetSdk 34
|
|
216
|
+
versionCode 1
|
|
217
|
+
versionName "${pkg.version}"
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
buildTypes {
|
|
221
|
+
release {
|
|
222
|
+
minifyEnabled true
|
|
223
|
+
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
dependencies {
|
|
229
|
+
implementation 'androidx.leanback:leanback:1.0.0'
|
|
230
|
+
}`;
|
|
231
|
+
await fs3.writeFile(path3.join(projectDir, "app/build.gradle"), buildGradle);
|
|
232
|
+
}
|
|
233
|
+
async createMainActivity(projectDir, pkg) {
|
|
234
|
+
const packageName = pkg.id || "com.example.app";
|
|
235
|
+
const activity = `package ${packageName};
|
|
236
|
+
|
|
237
|
+
import android.app.Activity;
|
|
238
|
+
import android.os.Bundle;
|
|
239
|
+
import android.webkit.WebView;
|
|
240
|
+
import android.webkit.WebSettings;
|
|
241
|
+
|
|
242
|
+
public class MainActivity extends Activity {
|
|
243
|
+
private WebView webView;
|
|
244
|
+
|
|
245
|
+
@Override
|
|
246
|
+
protected void onCreate(Bundle savedInstanceState) {
|
|
247
|
+
super.onCreate(savedInstanceState);
|
|
248
|
+
|
|
249
|
+
webView = new WebView(this);
|
|
250
|
+
setContentView(webView);
|
|
251
|
+
|
|
252
|
+
WebSettings settings = webView.getSettings();
|
|
253
|
+
settings.setJavaScriptEnabled(true);
|
|
254
|
+
settings.setDomStorageEnabled(true);
|
|
255
|
+
settings.setAllowFileAccess(true);
|
|
256
|
+
|
|
257
|
+
webView.loadUrl("file:///android_asset/www/index.html");
|
|
258
|
+
}
|
|
259
|
+
}`;
|
|
260
|
+
const activityPath = path3.join(
|
|
261
|
+
projectDir,
|
|
262
|
+
`app/src/main/java/${packageName.replace(/\./g, "/")}/MainActivity.java`
|
|
263
|
+
);
|
|
264
|
+
await fs3.ensureDir(path3.dirname(activityPath));
|
|
265
|
+
await fs3.writeFile(activityPath, activity);
|
|
266
|
+
}
|
|
267
|
+
async readPackageJson() {
|
|
268
|
+
try {
|
|
269
|
+
const pkg = await fs3.readJson("package.json");
|
|
270
|
+
return {
|
|
271
|
+
id: pkg.androidAppId || pkg.name.replace(/[^a-z0-9]/gi, ".").toLowerCase(),
|
|
272
|
+
name: pkg.name,
|
|
273
|
+
version: pkg.version,
|
|
274
|
+
description: pkg.description
|
|
275
|
+
};
|
|
276
|
+
} catch {
|
|
277
|
+
return {
|
|
278
|
+
id: "com.example.app",
|
|
279
|
+
name: "Table App",
|
|
280
|
+
version: "1.0.0"
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
// src/builder.ts
|
|
287
|
+
async function build(platform, options = {}) {
|
|
288
|
+
const opts = {
|
|
289
|
+
platform,
|
|
290
|
+
outDir: options.outDir || "dist",
|
|
291
|
+
minify: options.minify ?? true,
|
|
292
|
+
sourcemap: options.sourcemap ?? false
|
|
293
|
+
};
|
|
294
|
+
if (platform === "all") {
|
|
295
|
+
await Promise.all([
|
|
296
|
+
buildPlatform("tizen", opts),
|
|
297
|
+
buildPlatform("webos", opts),
|
|
298
|
+
buildPlatform("android", opts)
|
|
299
|
+
]);
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
await buildPlatform(platform, opts);
|
|
303
|
+
}
|
|
304
|
+
async function buildPlatform(platform, options) {
|
|
305
|
+
const adapter = getAdapter(platform);
|
|
306
|
+
await viteBuild({
|
|
307
|
+
build: {
|
|
308
|
+
outDir: `${options.outDir}/${platform}`,
|
|
309
|
+
minify: options.minify,
|
|
310
|
+
sourcemap: options.sourcemap,
|
|
311
|
+
emptyOutDir: true
|
|
312
|
+
},
|
|
313
|
+
define: {
|
|
314
|
+
__TABLE_PLATFORM__: JSON.stringify(platform)
|
|
315
|
+
}
|
|
316
|
+
});
|
|
317
|
+
await adapter.build(options);
|
|
318
|
+
const packagePath = await adapter.package(`${options.outDir}/${platform}`);
|
|
319
|
+
console.log(`\u2713 ${adapter.name} package created: ${packagePath}`);
|
|
320
|
+
}
|
|
321
|
+
function getAdapter(platform) {
|
|
322
|
+
switch (platform) {
|
|
323
|
+
case "tizen":
|
|
324
|
+
return new TizenAdapter();
|
|
325
|
+
case "webos":
|
|
326
|
+
return new WebOSAdapter();
|
|
327
|
+
case "android":
|
|
328
|
+
return new AndroidAdapter();
|
|
329
|
+
default:
|
|
330
|
+
throw new Error(`Unknown platform: ${platform}`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// src/cli.ts
|
|
335
|
+
var program = new Command();
|
|
336
|
+
program.name("table").description("Table.js build tool for Smart TV platforms").version("0.0.1");
|
|
337
|
+
program.command("build").description("Build for target platform").option("-p, --platform <platform>", "Target platform (tizen, webos, android, all)", "all").option("-o, --out <dir>", "Output directory", "dist").option("--no-minify", "Disable minification").option("--sourcemap", "Generate sourcemaps").action(async (options) => {
|
|
338
|
+
const platform = options.platform;
|
|
339
|
+
console.log();
|
|
340
|
+
console.log(chalk.bold(" table.js") + chalk.dim(" \u2014 Building for Smart TV"));
|
|
341
|
+
console.log();
|
|
342
|
+
const spinner = ora(`Building for ${platform}...`).start();
|
|
343
|
+
try {
|
|
344
|
+
await build(platform, {
|
|
345
|
+
outDir: options.out,
|
|
346
|
+
minify: options.minify,
|
|
347
|
+
sourcemap: options.sourcemap
|
|
348
|
+
});
|
|
349
|
+
spinner.succeed("Build complete!");
|
|
350
|
+
console.log();
|
|
351
|
+
} catch (error) {
|
|
352
|
+
spinner.fail("Build failed");
|
|
353
|
+
console.error(error);
|
|
354
|
+
process.exit(1);
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
program.parse();
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
type Platform = 'tizen' | 'webos' | 'android' | 'all';
|
|
2
|
+
interface BuildOptions {
|
|
3
|
+
platform: Platform;
|
|
4
|
+
outDir: string;
|
|
5
|
+
minify: boolean;
|
|
6
|
+
sourcemap: boolean;
|
|
7
|
+
}
|
|
8
|
+
interface PlatformAdapter {
|
|
9
|
+
name: string;
|
|
10
|
+
build(options: BuildOptions): Promise<void>;
|
|
11
|
+
package(distDir: string): Promise<string>;
|
|
12
|
+
}
|
|
13
|
+
interface ManifestBase {
|
|
14
|
+
id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
version: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
icon?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
declare function build(platform: Platform, options?: Partial<BuildOptions>): Promise<void>;
|
|
22
|
+
|
|
23
|
+
declare class TizenAdapter implements PlatformAdapter {
|
|
24
|
+
name: string;
|
|
25
|
+
build(options: BuildOptions): Promise<void>;
|
|
26
|
+
package(distDir: string): Promise<string>;
|
|
27
|
+
private createConfig;
|
|
28
|
+
private readPackageJson;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
declare class WebOSAdapter implements PlatformAdapter {
|
|
32
|
+
name: string;
|
|
33
|
+
build(options: BuildOptions): Promise<void>;
|
|
34
|
+
package(distDir: string): Promise<string>;
|
|
35
|
+
private createAppInfo;
|
|
36
|
+
private readPackageJson;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
declare class AndroidAdapter implements PlatformAdapter {
|
|
40
|
+
name: string;
|
|
41
|
+
build(options: BuildOptions): Promise<void>;
|
|
42
|
+
package(distDir: string): Promise<string>;
|
|
43
|
+
private createWebViewProject;
|
|
44
|
+
private createManifest;
|
|
45
|
+
private createGradleFiles;
|
|
46
|
+
private createMainActivity;
|
|
47
|
+
private readPackageJson;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export { AndroidAdapter, type BuildOptions, type ManifestBase, type Platform, type PlatformAdapter, TizenAdapter, WebOSAdapter, build };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
type Platform = 'tizen' | 'webos' | 'android' | 'all';
|
|
2
|
+
interface BuildOptions {
|
|
3
|
+
platform: Platform;
|
|
4
|
+
outDir: string;
|
|
5
|
+
minify: boolean;
|
|
6
|
+
sourcemap: boolean;
|
|
7
|
+
}
|
|
8
|
+
interface PlatformAdapter {
|
|
9
|
+
name: string;
|
|
10
|
+
build(options: BuildOptions): Promise<void>;
|
|
11
|
+
package(distDir: string): Promise<string>;
|
|
12
|
+
}
|
|
13
|
+
interface ManifestBase {
|
|
14
|
+
id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
version: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
icon?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
declare function build(platform: Platform, options?: Partial<BuildOptions>): Promise<void>;
|
|
22
|
+
|
|
23
|
+
declare class TizenAdapter implements PlatformAdapter {
|
|
24
|
+
name: string;
|
|
25
|
+
build(options: BuildOptions): Promise<void>;
|
|
26
|
+
package(distDir: string): Promise<string>;
|
|
27
|
+
private createConfig;
|
|
28
|
+
private readPackageJson;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
declare class WebOSAdapter implements PlatformAdapter {
|
|
32
|
+
name: string;
|
|
33
|
+
build(options: BuildOptions): Promise<void>;
|
|
34
|
+
package(distDir: string): Promise<string>;
|
|
35
|
+
private createAppInfo;
|
|
36
|
+
private readPackageJson;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
declare class AndroidAdapter implements PlatformAdapter {
|
|
40
|
+
name: string;
|
|
41
|
+
build(options: BuildOptions): Promise<void>;
|
|
42
|
+
package(distDir: string): Promise<string>;
|
|
43
|
+
private createWebViewProject;
|
|
44
|
+
private createManifest;
|
|
45
|
+
private createGradleFiles;
|
|
46
|
+
private createMainActivity;
|
|
47
|
+
private readPackageJson;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export { AndroidAdapter, type BuildOptions, type ManifestBase, type Platform, type PlatformAdapter, TizenAdapter, WebOSAdapter, build };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
AndroidAdapter: () => AndroidAdapter,
|
|
34
|
+
TizenAdapter: () => TizenAdapter,
|
|
35
|
+
WebOSAdapter: () => WebOSAdapter,
|
|
36
|
+
build: () => build
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(index_exports);
|
|
39
|
+
|
|
40
|
+
// src/builder.ts
|
|
41
|
+
var import_vite = require("vite");
|
|
42
|
+
|
|
43
|
+
// src/adapters/tizen.ts
|
|
44
|
+
var import_path = __toESM(require("path"));
|
|
45
|
+
var import_fs_extra = __toESM(require("fs-extra"));
|
|
46
|
+
var import_archiver = __toESM(require("archiver"));
|
|
47
|
+
var import_fs = require("fs");
|
|
48
|
+
var TizenAdapter = class {
|
|
49
|
+
name = "Tizen (Samsung)";
|
|
50
|
+
async build(options) {
|
|
51
|
+
const distDir = `${options.outDir}/tizen`;
|
|
52
|
+
await this.createConfig(distDir);
|
|
53
|
+
}
|
|
54
|
+
async package(distDir) {
|
|
55
|
+
const outputPath = import_path.default.join(distDir, "..", "app.wgt");
|
|
56
|
+
await new Promise((resolve, reject) => {
|
|
57
|
+
const output = (0, import_fs.createWriteStream)(outputPath);
|
|
58
|
+
const archive = (0, import_archiver.default)("zip", { zlib: { level: 9 } });
|
|
59
|
+
output.on("close", () => resolve());
|
|
60
|
+
archive.on("error", reject);
|
|
61
|
+
archive.pipe(output);
|
|
62
|
+
archive.directory(distDir, false);
|
|
63
|
+
archive.finalize();
|
|
64
|
+
});
|
|
65
|
+
return outputPath;
|
|
66
|
+
}
|
|
67
|
+
async createConfig(distDir) {
|
|
68
|
+
const pkg = await this.readPackageJson();
|
|
69
|
+
const config = `<?xml version="1.0" encoding="UTF-8"?>
|
|
70
|
+
<widget xmlns="http://www.w3.org/ns/widgets"
|
|
71
|
+
xmlns:tizen="http://tizen.org/ns/widgets"
|
|
72
|
+
id="${pkg.id || "com.example.app"}"
|
|
73
|
+
version="${pkg.version}"
|
|
74
|
+
viewmodes="maximized">
|
|
75
|
+
<tizen:application id="${pkg.id || "com.example.app"}.App"
|
|
76
|
+
package="${pkg.id || "com.example.app"}"
|
|
77
|
+
required_version="6.0"/>
|
|
78
|
+
<content src="index.html"/>
|
|
79
|
+
<feature name="http://tizen.org/feature/screen.size.all"/>
|
|
80
|
+
<icon src="icon.png"/>
|
|
81
|
+
<name>${pkg.name}</name>
|
|
82
|
+
<tizen:profile name="tv"/>
|
|
83
|
+
<tizen:setting screen-orientation="landscape"
|
|
84
|
+
context-menu="disable"
|
|
85
|
+
background-support="disable"
|
|
86
|
+
encryption="disable"
|
|
87
|
+
install-location="auto"/>
|
|
88
|
+
</widget>`;
|
|
89
|
+
await import_fs_extra.default.writeFile(import_path.default.join(distDir, "config.xml"), config);
|
|
90
|
+
}
|
|
91
|
+
async readPackageJson() {
|
|
92
|
+
try {
|
|
93
|
+
const pkg = await import_fs_extra.default.readJson("package.json");
|
|
94
|
+
return {
|
|
95
|
+
id: pkg.tizenAppId || pkg.name,
|
|
96
|
+
name: pkg.name,
|
|
97
|
+
version: pkg.version,
|
|
98
|
+
description: pkg.description
|
|
99
|
+
};
|
|
100
|
+
} catch {
|
|
101
|
+
return {
|
|
102
|
+
id: "com.example.app",
|
|
103
|
+
name: "Table App",
|
|
104
|
+
version: "1.0.0"
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
// src/adapters/webos.ts
|
|
111
|
+
var import_path2 = __toESM(require("path"));
|
|
112
|
+
var import_fs_extra2 = __toESM(require("fs-extra"));
|
|
113
|
+
var import_archiver2 = __toESM(require("archiver"));
|
|
114
|
+
var import_fs2 = require("fs");
|
|
115
|
+
var WebOSAdapter = class {
|
|
116
|
+
name = "webOS (LG)";
|
|
117
|
+
async build(options) {
|
|
118
|
+
const distDir = `${options.outDir}/webos`;
|
|
119
|
+
await this.createAppInfo(distDir);
|
|
120
|
+
}
|
|
121
|
+
async package(distDir) {
|
|
122
|
+
const outputPath = import_path2.default.join(distDir, "..", "app.ipk");
|
|
123
|
+
await new Promise((resolve, reject) => {
|
|
124
|
+
const output = (0, import_fs2.createWriteStream)(outputPath);
|
|
125
|
+
const archive = (0, import_archiver2.default)("tar", { gzip: true });
|
|
126
|
+
output.on("close", () => resolve());
|
|
127
|
+
archive.on("error", reject);
|
|
128
|
+
archive.pipe(output);
|
|
129
|
+
archive.directory(distDir, false);
|
|
130
|
+
archive.finalize();
|
|
131
|
+
});
|
|
132
|
+
return outputPath;
|
|
133
|
+
}
|
|
134
|
+
async createAppInfo(distDir) {
|
|
135
|
+
const pkg = await this.readPackageJson();
|
|
136
|
+
const appInfo = {
|
|
137
|
+
id: pkg.id || "com.example.app",
|
|
138
|
+
version: pkg.version,
|
|
139
|
+
vendor: "Table.js",
|
|
140
|
+
type: "web",
|
|
141
|
+
main: "index.html",
|
|
142
|
+
title: pkg.name,
|
|
143
|
+
icon: "icon.png",
|
|
144
|
+
largeIcon: "icon.png",
|
|
145
|
+
bgImage: "splash.png",
|
|
146
|
+
resolution: "1920x1080",
|
|
147
|
+
disallowScrollingInMainWindow: true
|
|
148
|
+
};
|
|
149
|
+
await import_fs_extra2.default.writeJson(import_path2.default.join(distDir, "appinfo.json"), appInfo, { spaces: 2 });
|
|
150
|
+
}
|
|
151
|
+
async readPackageJson() {
|
|
152
|
+
try {
|
|
153
|
+
const pkg = await import_fs_extra2.default.readJson("package.json");
|
|
154
|
+
return {
|
|
155
|
+
id: pkg.webosAppId || pkg.name,
|
|
156
|
+
name: pkg.name,
|
|
157
|
+
version: pkg.version,
|
|
158
|
+
description: pkg.description
|
|
159
|
+
};
|
|
160
|
+
} catch {
|
|
161
|
+
return {
|
|
162
|
+
id: "com.example.app",
|
|
163
|
+
name: "Table App",
|
|
164
|
+
version: "1.0.0"
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
// src/adapters/android.ts
|
|
171
|
+
var import_path3 = __toESM(require("path"));
|
|
172
|
+
var import_fs_extra3 = __toESM(require("fs-extra"));
|
|
173
|
+
var import_execa = require("execa");
|
|
174
|
+
var AndroidAdapter = class {
|
|
175
|
+
name = "Android TV";
|
|
176
|
+
async build(options) {
|
|
177
|
+
const distDir = `${options.outDir}/android`;
|
|
178
|
+
await this.createWebViewProject(distDir);
|
|
179
|
+
}
|
|
180
|
+
async package(distDir) {
|
|
181
|
+
const projectDir = import_path3.default.join(distDir, "android-project");
|
|
182
|
+
try {
|
|
183
|
+
await (0, import_execa.execa)("./gradlew", ["assembleRelease"], {
|
|
184
|
+
cwd: projectDir,
|
|
185
|
+
stdio: "inherit"
|
|
186
|
+
});
|
|
187
|
+
const apkPath = import_path3.default.join(projectDir, "app/build/outputs/apk/release/app-release.apk");
|
|
188
|
+
const outputPath = import_path3.default.join(distDir, "..", "app.apk");
|
|
189
|
+
await import_fs_extra3.default.copy(apkPath, outputPath);
|
|
190
|
+
return outputPath;
|
|
191
|
+
} catch (error) {
|
|
192
|
+
throw new Error("Android build failed. Make sure Android SDK is installed.");
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
async createWebViewProject(distDir) {
|
|
196
|
+
const pkg = await this.readPackageJson();
|
|
197
|
+
const projectDir = import_path3.default.join(distDir, "android-project");
|
|
198
|
+
await import_fs_extra3.default.ensureDir(projectDir);
|
|
199
|
+
await import_fs_extra3.default.copy(distDir, import_path3.default.join(projectDir, "app/src/main/assets/www"));
|
|
200
|
+
await this.createManifest(projectDir, pkg);
|
|
201
|
+
await this.createGradleFiles(projectDir, pkg);
|
|
202
|
+
await this.createMainActivity(projectDir, pkg);
|
|
203
|
+
}
|
|
204
|
+
async createManifest(projectDir, pkg) {
|
|
205
|
+
const manifest = `<?xml version="1.0" encoding="utf-8"?>
|
|
206
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
207
|
+
package="${pkg.id || "com.example.app"}">
|
|
208
|
+
|
|
209
|
+
<uses-permission android:name="android.permission.INTERNET" />
|
|
210
|
+
<uses-feature android:name="android.software.leanback" android:required="true" />
|
|
211
|
+
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
|
|
212
|
+
|
|
213
|
+
<application
|
|
214
|
+
android:allowBackup="true"
|
|
215
|
+
android:icon="@mipmap/ic_launcher"
|
|
216
|
+
android:label="${pkg.name}"
|
|
217
|
+
android:banner="@drawable/banner"
|
|
218
|
+
android:theme="@style/Theme.Leanback">
|
|
219
|
+
|
|
220
|
+
<activity
|
|
221
|
+
android:name=".MainActivity"
|
|
222
|
+
android:exported="true"
|
|
223
|
+
android:screenOrientation="landscape">
|
|
224
|
+
<intent-filter>
|
|
225
|
+
<action android:name="android.intent.action.MAIN" />
|
|
226
|
+
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
|
|
227
|
+
</intent-filter>
|
|
228
|
+
</activity>
|
|
229
|
+
</application>
|
|
230
|
+
</manifest>`;
|
|
231
|
+
const manifestPath = import_path3.default.join(projectDir, "app/src/main/AndroidManifest.xml");
|
|
232
|
+
await import_fs_extra3.default.ensureDir(import_path3.default.dirname(manifestPath));
|
|
233
|
+
await import_fs_extra3.default.writeFile(manifestPath, manifest);
|
|
234
|
+
}
|
|
235
|
+
async createGradleFiles(projectDir, pkg) {
|
|
236
|
+
const buildGradle = `plugins {
|
|
237
|
+
id 'com.android.application'
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
android {
|
|
241
|
+
namespace '${pkg.id || "com.example.app"}'
|
|
242
|
+
compileSdk 34
|
|
243
|
+
|
|
244
|
+
defaultConfig {
|
|
245
|
+
applicationId "${pkg.id || "com.example.app"}"
|
|
246
|
+
minSdk 21
|
|
247
|
+
targetSdk 34
|
|
248
|
+
versionCode 1
|
|
249
|
+
versionName "${pkg.version}"
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
buildTypes {
|
|
253
|
+
release {
|
|
254
|
+
minifyEnabled true
|
|
255
|
+
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
dependencies {
|
|
261
|
+
implementation 'androidx.leanback:leanback:1.0.0'
|
|
262
|
+
}`;
|
|
263
|
+
await import_fs_extra3.default.writeFile(import_path3.default.join(projectDir, "app/build.gradle"), buildGradle);
|
|
264
|
+
}
|
|
265
|
+
async createMainActivity(projectDir, pkg) {
|
|
266
|
+
const packageName = pkg.id || "com.example.app";
|
|
267
|
+
const activity = `package ${packageName};
|
|
268
|
+
|
|
269
|
+
import android.app.Activity;
|
|
270
|
+
import android.os.Bundle;
|
|
271
|
+
import android.webkit.WebView;
|
|
272
|
+
import android.webkit.WebSettings;
|
|
273
|
+
|
|
274
|
+
public class MainActivity extends Activity {
|
|
275
|
+
private WebView webView;
|
|
276
|
+
|
|
277
|
+
@Override
|
|
278
|
+
protected void onCreate(Bundle savedInstanceState) {
|
|
279
|
+
super.onCreate(savedInstanceState);
|
|
280
|
+
|
|
281
|
+
webView = new WebView(this);
|
|
282
|
+
setContentView(webView);
|
|
283
|
+
|
|
284
|
+
WebSettings settings = webView.getSettings();
|
|
285
|
+
settings.setJavaScriptEnabled(true);
|
|
286
|
+
settings.setDomStorageEnabled(true);
|
|
287
|
+
settings.setAllowFileAccess(true);
|
|
288
|
+
|
|
289
|
+
webView.loadUrl("file:///android_asset/www/index.html");
|
|
290
|
+
}
|
|
291
|
+
}`;
|
|
292
|
+
const activityPath = import_path3.default.join(
|
|
293
|
+
projectDir,
|
|
294
|
+
`app/src/main/java/${packageName.replace(/\./g, "/")}/MainActivity.java`
|
|
295
|
+
);
|
|
296
|
+
await import_fs_extra3.default.ensureDir(import_path3.default.dirname(activityPath));
|
|
297
|
+
await import_fs_extra3.default.writeFile(activityPath, activity);
|
|
298
|
+
}
|
|
299
|
+
async readPackageJson() {
|
|
300
|
+
try {
|
|
301
|
+
const pkg = await import_fs_extra3.default.readJson("package.json");
|
|
302
|
+
return {
|
|
303
|
+
id: pkg.androidAppId || pkg.name.replace(/[^a-z0-9]/gi, ".").toLowerCase(),
|
|
304
|
+
name: pkg.name,
|
|
305
|
+
version: pkg.version,
|
|
306
|
+
description: pkg.description
|
|
307
|
+
};
|
|
308
|
+
} catch {
|
|
309
|
+
return {
|
|
310
|
+
id: "com.example.app",
|
|
311
|
+
name: "Table App",
|
|
312
|
+
version: "1.0.0"
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
// src/builder.ts
|
|
319
|
+
async function build(platform, options = {}) {
|
|
320
|
+
const opts = {
|
|
321
|
+
platform,
|
|
322
|
+
outDir: options.outDir || "dist",
|
|
323
|
+
minify: options.minify ?? true,
|
|
324
|
+
sourcemap: options.sourcemap ?? false
|
|
325
|
+
};
|
|
326
|
+
if (platform === "all") {
|
|
327
|
+
await Promise.all([
|
|
328
|
+
buildPlatform("tizen", opts),
|
|
329
|
+
buildPlatform("webos", opts),
|
|
330
|
+
buildPlatform("android", opts)
|
|
331
|
+
]);
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
await buildPlatform(platform, opts);
|
|
335
|
+
}
|
|
336
|
+
async function buildPlatform(platform, options) {
|
|
337
|
+
const adapter = getAdapter(platform);
|
|
338
|
+
await (0, import_vite.build)({
|
|
339
|
+
build: {
|
|
340
|
+
outDir: `${options.outDir}/${platform}`,
|
|
341
|
+
minify: options.minify,
|
|
342
|
+
sourcemap: options.sourcemap,
|
|
343
|
+
emptyOutDir: true
|
|
344
|
+
},
|
|
345
|
+
define: {
|
|
346
|
+
__TABLE_PLATFORM__: JSON.stringify(platform)
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
await adapter.build(options);
|
|
350
|
+
const packagePath = await adapter.package(`${options.outDir}/${platform}`);
|
|
351
|
+
console.log(`\u2713 ${adapter.name} package created: ${packagePath}`);
|
|
352
|
+
}
|
|
353
|
+
function getAdapter(platform) {
|
|
354
|
+
switch (platform) {
|
|
355
|
+
case "tizen":
|
|
356
|
+
return new TizenAdapter();
|
|
357
|
+
case "webos":
|
|
358
|
+
return new WebOSAdapter();
|
|
359
|
+
case "android":
|
|
360
|
+
return new AndroidAdapter();
|
|
361
|
+
default:
|
|
362
|
+
throw new Error(`Unknown platform: ${platform}`);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
366
|
+
0 && (module.exports = {
|
|
367
|
+
AndroidAdapter,
|
|
368
|
+
TizenAdapter,
|
|
369
|
+
WebOSAdapter,
|
|
370
|
+
build
|
|
371
|
+
});
|
|
372
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/builder.ts","../src/adapters/tizen.ts","../src/adapters/webos.ts","../src/adapters/android.ts"],"sourcesContent":["export { build } from './builder'\nexport type { Platform, BuildOptions, PlatformAdapter, ManifestBase } from './types'\nexport { TizenAdapter } from './adapters/tizen'\nexport { WebOSAdapter } from './adapters/webos'\nexport { AndroidAdapter } from './adapters/android'\n","import { build as viteBuild } from 'vite'\nimport type { BuildOptions, Platform, PlatformAdapter } from './types'\nimport { TizenAdapter } from './adapters/tizen'\nimport { WebOSAdapter } from './adapters/webos'\nimport { AndroidAdapter } from './adapters/android'\n\nexport async function build(platform: Platform, options: Partial<BuildOptions> = {}) {\n const opts: BuildOptions = {\n platform,\n outDir: options.outDir || 'dist',\n minify: options.minify ?? true,\n sourcemap: options.sourcemap ?? false,\n }\n\n if (platform === 'all') {\n await Promise.all([\n buildPlatform('tizen', opts),\n buildPlatform('webos', opts),\n buildPlatform('android', opts),\n ])\n return\n }\n\n await buildPlatform(platform, opts)\n}\n\nasync function buildPlatform(platform: Platform, options: BuildOptions) {\n const adapter = getAdapter(platform)\n\n await viteBuild({\n build: {\n outDir: `${options.outDir}/${platform}`,\n minify: options.minify,\n sourcemap: options.sourcemap,\n emptyOutDir: true,\n },\n define: {\n __TABLE_PLATFORM__: JSON.stringify(platform),\n },\n })\n\n await adapter.build(options)\n\n const packagePath = await adapter.package(`${options.outDir}/${platform}`)\n console.log(`✓ ${adapter.name} package created: ${packagePath}`)\n}\n\nfunction getAdapter(platform: Platform): PlatformAdapter {\n switch (platform) {\n case 'tizen':\n return new TizenAdapter()\n case 'webos':\n return new WebOSAdapter()\n case 'android':\n return new AndroidAdapter()\n default:\n throw new Error(`Unknown platform: ${platform}`)\n }\n}\n","import path from 'path'\nimport fs from 'fs-extra'\nimport archiver from 'archiver'\nimport { createWriteStream } from 'fs'\nimport type { BuildOptions, PlatformAdapter, ManifestBase } from '../types'\n\nexport class TizenAdapter implements PlatformAdapter {\n name = 'Tizen (Samsung)'\n\n async build(options: BuildOptions): Promise<void> {\n const distDir = `${options.outDir}/tizen`\n await this.createConfig(distDir)\n }\n\n async package(distDir: string): Promise<string> {\n const outputPath = path.join(distDir, '..', 'app.wgt')\n\n await new Promise<void>((resolve, reject) => {\n const output = createWriteStream(outputPath)\n const archive = archiver('zip', { zlib: { level: 9 } })\n\n output.on('close', () => resolve())\n archive.on('error', reject)\n\n archive.pipe(output)\n archive.directory(distDir, false)\n archive.finalize()\n })\n\n return outputPath\n }\n\n private async createConfig(distDir: string) {\n const pkg = await this.readPackageJson()\n\n const config = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<widget xmlns=\"http://www.w3.org/ns/widgets\" \n xmlns:tizen=\"http://tizen.org/ns/widgets\"\n id=\"${pkg.id || 'com.example.app'}\"\n version=\"${pkg.version}\"\n viewmodes=\"maximized\">\n <tizen:application id=\"${pkg.id || 'com.example.app'}.App\" \n package=\"${pkg.id || 'com.example.app'}\"\n required_version=\"6.0\"/>\n <content src=\"index.html\"/>\n <feature name=\"http://tizen.org/feature/screen.size.all\"/>\n <icon src=\"icon.png\"/>\n <name>${pkg.name}</name>\n <tizen:profile name=\"tv\"/>\n <tizen:setting screen-orientation=\"landscape\" \n context-menu=\"disable\" \n background-support=\"disable\" \n encryption=\"disable\" \n install-location=\"auto\"/>\n</widget>`\n\n await fs.writeFile(path.join(distDir, 'config.xml'), config)\n }\n\n private async readPackageJson(): Promise<ManifestBase> {\n try {\n const pkg = await fs.readJson('package.json')\n return {\n id: pkg.tizenAppId || pkg.name,\n name: pkg.name,\n version: pkg.version,\n description: pkg.description,\n }\n } catch {\n return {\n id: 'com.example.app',\n name: 'Table App',\n version: '1.0.0',\n }\n }\n }\n}\n","import path from 'path'\nimport fs from 'fs-extra'\nimport archiver from 'archiver'\nimport { createWriteStream } from 'fs'\nimport type { BuildOptions, PlatformAdapter, ManifestBase } from '../types'\n\nexport class WebOSAdapter implements PlatformAdapter {\n name = 'webOS (LG)'\n\n async build(options: BuildOptions): Promise<void> {\n const distDir = `${options.outDir}/webos`\n await this.createAppInfo(distDir)\n }\n\n async package(distDir: string): Promise<string> {\n const outputPath = path.join(distDir, '..', 'app.ipk')\n\n await new Promise<void>((resolve, reject) => {\n const output = createWriteStream(outputPath)\n const archive = archiver('tar', { gzip: true })\n\n output.on('close', () => resolve())\n archive.on('error', reject)\n\n archive.pipe(output)\n archive.directory(distDir, false)\n archive.finalize()\n })\n\n return outputPath\n }\n\n private async createAppInfo(distDir: string) {\n const pkg = await this.readPackageJson()\n\n const appInfo = {\n id: pkg.id || 'com.example.app',\n version: pkg.version,\n vendor: 'Table.js',\n type: 'web',\n main: 'index.html',\n title: pkg.name,\n icon: 'icon.png',\n largeIcon: 'icon.png',\n bgImage: 'splash.png',\n resolution: '1920x1080',\n disallowScrollingInMainWindow: true,\n }\n\n await fs.writeJson(path.join(distDir, 'appinfo.json'), appInfo, { spaces: 2 })\n }\n\n private async readPackageJson(): Promise<ManifestBase> {\n try {\n const pkg = await fs.readJson('package.json')\n return {\n id: pkg.webosAppId || pkg.name,\n name: pkg.name,\n version: pkg.version,\n description: pkg.description,\n }\n } catch {\n return {\n id: 'com.example.app',\n name: 'Table App',\n version: '1.0.0',\n }\n }\n }\n}\n","import path from 'path'\nimport fs from 'fs-extra'\nimport { execa } from 'execa'\nimport type { BuildOptions, PlatformAdapter, ManifestBase } from '../types'\n\nexport class AndroidAdapter implements PlatformAdapter {\n name = 'Android TV'\n\n async build(options: BuildOptions): Promise<void> {\n const distDir = `${options.outDir}/android`\n await this.createWebViewProject(distDir)\n }\n\n async package(distDir: string): Promise<string> {\n const projectDir = path.join(distDir, 'android-project')\n\n try {\n await execa('./gradlew', ['assembleRelease'], {\n cwd: projectDir,\n stdio: 'inherit',\n })\n\n const apkPath = path.join(projectDir, 'app/build/outputs/apk/release/app-release.apk')\n\n const outputPath = path.join(distDir, '..', 'app.apk')\n await fs.copy(apkPath, outputPath)\n\n return outputPath\n } catch (error) {\n throw new Error('Android build failed. Make sure Android SDK is installed.')\n }\n }\n\n private async createWebViewProject(distDir: string) {\n const pkg = await this.readPackageJson()\n const projectDir = path.join(distDir, 'android-project')\n\n await fs.ensureDir(projectDir)\n await fs.copy(distDir, path.join(projectDir, 'app/src/main/assets/www'))\n\n await this.createManifest(projectDir, pkg)\n await this.createGradleFiles(projectDir, pkg)\n await this.createMainActivity(projectDir, pkg)\n }\n\n private async createManifest(projectDir: string, pkg: ManifestBase) {\n const manifest = `<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"${pkg.id || 'com.example.app'}\">\n\n <uses-permission android:name=\"android.permission.INTERNET\" />\n <uses-feature android:name=\"android.software.leanback\" android:required=\"true\" />\n <uses-feature android:name=\"android.hardware.touchscreen\" android:required=\"false\" />\n\n <application\n android:allowBackup=\"true\"\n android:icon=\"@mipmap/ic_launcher\"\n android:label=\"${pkg.name}\"\n android:banner=\"@drawable/banner\"\n android:theme=\"@style/Theme.Leanback\">\n \n <activity\n android:name=\".MainActivity\"\n android:exported=\"true\"\n android:screenOrientation=\"landscape\">\n <intent-filter>\n <action android:name=\"android.intent.action.MAIN\" />\n <category android:name=\"android.intent.category.LEANBACK_LAUNCHER\" />\n </intent-filter>\n </activity>\n </application>\n</manifest>`\n\n const manifestPath = path.join(projectDir, 'app/src/main/AndroidManifest.xml')\n await fs.ensureDir(path.dirname(manifestPath))\n await fs.writeFile(manifestPath, manifest)\n }\n\n private async createGradleFiles(projectDir: string, pkg: ManifestBase) {\n const buildGradle = `plugins {\n id 'com.android.application'\n}\n\nandroid {\n namespace '${pkg.id || 'com.example.app'}'\n compileSdk 34\n\n defaultConfig {\n applicationId \"${pkg.id || 'com.example.app'}\"\n minSdk 21\n targetSdk 34\n versionCode 1\n versionName \"${pkg.version}\"\n }\n\n buildTypes {\n release {\n minifyEnabled true\n proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')\n }\n }\n}\n\ndependencies {\n implementation 'androidx.leanback:leanback:1.0.0'\n}`\n\n await fs.writeFile(path.join(projectDir, 'app/build.gradle'), buildGradle)\n }\n\n private async createMainActivity(projectDir: string, pkg: ManifestBase) {\n const packageName = pkg.id || 'com.example.app'\n const activity = `package ${packageName};\n\nimport android.app.Activity;\nimport android.os.Bundle;\nimport android.webkit.WebView;\nimport android.webkit.WebSettings;\n\npublic class MainActivity extends Activity {\n private WebView webView;\n\n @Override\n protected void onCreate(Bundle savedInstanceState) {\n super.onCreate(savedInstanceState);\n \n webView = new WebView(this);\n setContentView(webView);\n \n WebSettings settings = webView.getSettings();\n settings.setJavaScriptEnabled(true);\n settings.setDomStorageEnabled(true);\n settings.setAllowFileAccess(true);\n \n webView.loadUrl(\"file:///android_asset/www/index.html\");\n }\n}`\n\n const activityPath = path.join(\n projectDir,\n `app/src/main/java/${packageName.replace(/\\./g, '/')}/MainActivity.java`,\n )\n await fs.ensureDir(path.dirname(activityPath))\n await fs.writeFile(activityPath, activity)\n }\n\n private async readPackageJson(): Promise<ManifestBase> {\n try {\n const pkg = await fs.readJson('package.json')\n return {\n id: pkg.androidAppId || pkg.name.replace(/[^a-z0-9]/gi, '.').toLowerCase(),\n name: pkg.name,\n version: pkg.version,\n description: pkg.description,\n }\n } catch {\n return {\n id: 'com.example.app',\n name: 'Table App',\n version: '1.0.0',\n }\n }\n }\n}\n"],"mappings":"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","names":["path","archiver","fs","import_path","import_fs_extra","import_archiver","import_fs","path","archiver","fs","import_path","import_fs_extra","path","fs","viteBuild"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
// src/builder.ts
|
|
2
|
+
import { build as viteBuild } from "vite";
|
|
3
|
+
|
|
4
|
+
// src/adapters/tizen.ts
|
|
5
|
+
import path from "path";
|
|
6
|
+
import fs from "fs-extra";
|
|
7
|
+
import archiver from "archiver";
|
|
8
|
+
import { createWriteStream } from "fs";
|
|
9
|
+
var TizenAdapter = class {
|
|
10
|
+
name = "Tizen (Samsung)";
|
|
11
|
+
async build(options) {
|
|
12
|
+
const distDir = `${options.outDir}/tizen`;
|
|
13
|
+
await this.createConfig(distDir);
|
|
14
|
+
}
|
|
15
|
+
async package(distDir) {
|
|
16
|
+
const outputPath = path.join(distDir, "..", "app.wgt");
|
|
17
|
+
await new Promise((resolve, reject) => {
|
|
18
|
+
const output = createWriteStream(outputPath);
|
|
19
|
+
const archive = archiver("zip", { zlib: { level: 9 } });
|
|
20
|
+
output.on("close", () => resolve());
|
|
21
|
+
archive.on("error", reject);
|
|
22
|
+
archive.pipe(output);
|
|
23
|
+
archive.directory(distDir, false);
|
|
24
|
+
archive.finalize();
|
|
25
|
+
});
|
|
26
|
+
return outputPath;
|
|
27
|
+
}
|
|
28
|
+
async createConfig(distDir) {
|
|
29
|
+
const pkg = await this.readPackageJson();
|
|
30
|
+
const config = `<?xml version="1.0" encoding="UTF-8"?>
|
|
31
|
+
<widget xmlns="http://www.w3.org/ns/widgets"
|
|
32
|
+
xmlns:tizen="http://tizen.org/ns/widgets"
|
|
33
|
+
id="${pkg.id || "com.example.app"}"
|
|
34
|
+
version="${pkg.version}"
|
|
35
|
+
viewmodes="maximized">
|
|
36
|
+
<tizen:application id="${pkg.id || "com.example.app"}.App"
|
|
37
|
+
package="${pkg.id || "com.example.app"}"
|
|
38
|
+
required_version="6.0"/>
|
|
39
|
+
<content src="index.html"/>
|
|
40
|
+
<feature name="http://tizen.org/feature/screen.size.all"/>
|
|
41
|
+
<icon src="icon.png"/>
|
|
42
|
+
<name>${pkg.name}</name>
|
|
43
|
+
<tizen:profile name="tv"/>
|
|
44
|
+
<tizen:setting screen-orientation="landscape"
|
|
45
|
+
context-menu="disable"
|
|
46
|
+
background-support="disable"
|
|
47
|
+
encryption="disable"
|
|
48
|
+
install-location="auto"/>
|
|
49
|
+
</widget>`;
|
|
50
|
+
await fs.writeFile(path.join(distDir, "config.xml"), config);
|
|
51
|
+
}
|
|
52
|
+
async readPackageJson() {
|
|
53
|
+
try {
|
|
54
|
+
const pkg = await fs.readJson("package.json");
|
|
55
|
+
return {
|
|
56
|
+
id: pkg.tizenAppId || pkg.name,
|
|
57
|
+
name: pkg.name,
|
|
58
|
+
version: pkg.version,
|
|
59
|
+
description: pkg.description
|
|
60
|
+
};
|
|
61
|
+
} catch {
|
|
62
|
+
return {
|
|
63
|
+
id: "com.example.app",
|
|
64
|
+
name: "Table App",
|
|
65
|
+
version: "1.0.0"
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// src/adapters/webos.ts
|
|
72
|
+
import path2 from "path";
|
|
73
|
+
import fs2 from "fs-extra";
|
|
74
|
+
import archiver2 from "archiver";
|
|
75
|
+
import { createWriteStream as createWriteStream2 } from "fs";
|
|
76
|
+
var WebOSAdapter = class {
|
|
77
|
+
name = "webOS (LG)";
|
|
78
|
+
async build(options) {
|
|
79
|
+
const distDir = `${options.outDir}/webos`;
|
|
80
|
+
await this.createAppInfo(distDir);
|
|
81
|
+
}
|
|
82
|
+
async package(distDir) {
|
|
83
|
+
const outputPath = path2.join(distDir, "..", "app.ipk");
|
|
84
|
+
await new Promise((resolve, reject) => {
|
|
85
|
+
const output = createWriteStream2(outputPath);
|
|
86
|
+
const archive = archiver2("tar", { gzip: true });
|
|
87
|
+
output.on("close", () => resolve());
|
|
88
|
+
archive.on("error", reject);
|
|
89
|
+
archive.pipe(output);
|
|
90
|
+
archive.directory(distDir, false);
|
|
91
|
+
archive.finalize();
|
|
92
|
+
});
|
|
93
|
+
return outputPath;
|
|
94
|
+
}
|
|
95
|
+
async createAppInfo(distDir) {
|
|
96
|
+
const pkg = await this.readPackageJson();
|
|
97
|
+
const appInfo = {
|
|
98
|
+
id: pkg.id || "com.example.app",
|
|
99
|
+
version: pkg.version,
|
|
100
|
+
vendor: "Table.js",
|
|
101
|
+
type: "web",
|
|
102
|
+
main: "index.html",
|
|
103
|
+
title: pkg.name,
|
|
104
|
+
icon: "icon.png",
|
|
105
|
+
largeIcon: "icon.png",
|
|
106
|
+
bgImage: "splash.png",
|
|
107
|
+
resolution: "1920x1080",
|
|
108
|
+
disallowScrollingInMainWindow: true
|
|
109
|
+
};
|
|
110
|
+
await fs2.writeJson(path2.join(distDir, "appinfo.json"), appInfo, { spaces: 2 });
|
|
111
|
+
}
|
|
112
|
+
async readPackageJson() {
|
|
113
|
+
try {
|
|
114
|
+
const pkg = await fs2.readJson("package.json");
|
|
115
|
+
return {
|
|
116
|
+
id: pkg.webosAppId || pkg.name,
|
|
117
|
+
name: pkg.name,
|
|
118
|
+
version: pkg.version,
|
|
119
|
+
description: pkg.description
|
|
120
|
+
};
|
|
121
|
+
} catch {
|
|
122
|
+
return {
|
|
123
|
+
id: "com.example.app",
|
|
124
|
+
name: "Table App",
|
|
125
|
+
version: "1.0.0"
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
// src/adapters/android.ts
|
|
132
|
+
import path3 from "path";
|
|
133
|
+
import fs3 from "fs-extra";
|
|
134
|
+
import { execa } from "execa";
|
|
135
|
+
var AndroidAdapter = class {
|
|
136
|
+
name = "Android TV";
|
|
137
|
+
async build(options) {
|
|
138
|
+
const distDir = `${options.outDir}/android`;
|
|
139
|
+
await this.createWebViewProject(distDir);
|
|
140
|
+
}
|
|
141
|
+
async package(distDir) {
|
|
142
|
+
const projectDir = path3.join(distDir, "android-project");
|
|
143
|
+
try {
|
|
144
|
+
await execa("./gradlew", ["assembleRelease"], {
|
|
145
|
+
cwd: projectDir,
|
|
146
|
+
stdio: "inherit"
|
|
147
|
+
});
|
|
148
|
+
const apkPath = path3.join(projectDir, "app/build/outputs/apk/release/app-release.apk");
|
|
149
|
+
const outputPath = path3.join(distDir, "..", "app.apk");
|
|
150
|
+
await fs3.copy(apkPath, outputPath);
|
|
151
|
+
return outputPath;
|
|
152
|
+
} catch (error) {
|
|
153
|
+
throw new Error("Android build failed. Make sure Android SDK is installed.");
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
async createWebViewProject(distDir) {
|
|
157
|
+
const pkg = await this.readPackageJson();
|
|
158
|
+
const projectDir = path3.join(distDir, "android-project");
|
|
159
|
+
await fs3.ensureDir(projectDir);
|
|
160
|
+
await fs3.copy(distDir, path3.join(projectDir, "app/src/main/assets/www"));
|
|
161
|
+
await this.createManifest(projectDir, pkg);
|
|
162
|
+
await this.createGradleFiles(projectDir, pkg);
|
|
163
|
+
await this.createMainActivity(projectDir, pkg);
|
|
164
|
+
}
|
|
165
|
+
async createManifest(projectDir, pkg) {
|
|
166
|
+
const manifest = `<?xml version="1.0" encoding="utf-8"?>
|
|
167
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
168
|
+
package="${pkg.id || "com.example.app"}">
|
|
169
|
+
|
|
170
|
+
<uses-permission android:name="android.permission.INTERNET" />
|
|
171
|
+
<uses-feature android:name="android.software.leanback" android:required="true" />
|
|
172
|
+
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
|
|
173
|
+
|
|
174
|
+
<application
|
|
175
|
+
android:allowBackup="true"
|
|
176
|
+
android:icon="@mipmap/ic_launcher"
|
|
177
|
+
android:label="${pkg.name}"
|
|
178
|
+
android:banner="@drawable/banner"
|
|
179
|
+
android:theme="@style/Theme.Leanback">
|
|
180
|
+
|
|
181
|
+
<activity
|
|
182
|
+
android:name=".MainActivity"
|
|
183
|
+
android:exported="true"
|
|
184
|
+
android:screenOrientation="landscape">
|
|
185
|
+
<intent-filter>
|
|
186
|
+
<action android:name="android.intent.action.MAIN" />
|
|
187
|
+
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
|
|
188
|
+
</intent-filter>
|
|
189
|
+
</activity>
|
|
190
|
+
</application>
|
|
191
|
+
</manifest>`;
|
|
192
|
+
const manifestPath = path3.join(projectDir, "app/src/main/AndroidManifest.xml");
|
|
193
|
+
await fs3.ensureDir(path3.dirname(manifestPath));
|
|
194
|
+
await fs3.writeFile(manifestPath, manifest);
|
|
195
|
+
}
|
|
196
|
+
async createGradleFiles(projectDir, pkg) {
|
|
197
|
+
const buildGradle = `plugins {
|
|
198
|
+
id 'com.android.application'
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
android {
|
|
202
|
+
namespace '${pkg.id || "com.example.app"}'
|
|
203
|
+
compileSdk 34
|
|
204
|
+
|
|
205
|
+
defaultConfig {
|
|
206
|
+
applicationId "${pkg.id || "com.example.app"}"
|
|
207
|
+
minSdk 21
|
|
208
|
+
targetSdk 34
|
|
209
|
+
versionCode 1
|
|
210
|
+
versionName "${pkg.version}"
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
buildTypes {
|
|
214
|
+
release {
|
|
215
|
+
minifyEnabled true
|
|
216
|
+
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
dependencies {
|
|
222
|
+
implementation 'androidx.leanback:leanback:1.0.0'
|
|
223
|
+
}`;
|
|
224
|
+
await fs3.writeFile(path3.join(projectDir, "app/build.gradle"), buildGradle);
|
|
225
|
+
}
|
|
226
|
+
async createMainActivity(projectDir, pkg) {
|
|
227
|
+
const packageName = pkg.id || "com.example.app";
|
|
228
|
+
const activity = `package ${packageName};
|
|
229
|
+
|
|
230
|
+
import android.app.Activity;
|
|
231
|
+
import android.os.Bundle;
|
|
232
|
+
import android.webkit.WebView;
|
|
233
|
+
import android.webkit.WebSettings;
|
|
234
|
+
|
|
235
|
+
public class MainActivity extends Activity {
|
|
236
|
+
private WebView webView;
|
|
237
|
+
|
|
238
|
+
@Override
|
|
239
|
+
protected void onCreate(Bundle savedInstanceState) {
|
|
240
|
+
super.onCreate(savedInstanceState);
|
|
241
|
+
|
|
242
|
+
webView = new WebView(this);
|
|
243
|
+
setContentView(webView);
|
|
244
|
+
|
|
245
|
+
WebSettings settings = webView.getSettings();
|
|
246
|
+
settings.setJavaScriptEnabled(true);
|
|
247
|
+
settings.setDomStorageEnabled(true);
|
|
248
|
+
settings.setAllowFileAccess(true);
|
|
249
|
+
|
|
250
|
+
webView.loadUrl("file:///android_asset/www/index.html");
|
|
251
|
+
}
|
|
252
|
+
}`;
|
|
253
|
+
const activityPath = path3.join(
|
|
254
|
+
projectDir,
|
|
255
|
+
`app/src/main/java/${packageName.replace(/\./g, "/")}/MainActivity.java`
|
|
256
|
+
);
|
|
257
|
+
await fs3.ensureDir(path3.dirname(activityPath));
|
|
258
|
+
await fs3.writeFile(activityPath, activity);
|
|
259
|
+
}
|
|
260
|
+
async readPackageJson() {
|
|
261
|
+
try {
|
|
262
|
+
const pkg = await fs3.readJson("package.json");
|
|
263
|
+
return {
|
|
264
|
+
id: pkg.androidAppId || pkg.name.replace(/[^a-z0-9]/gi, ".").toLowerCase(),
|
|
265
|
+
name: pkg.name,
|
|
266
|
+
version: pkg.version,
|
|
267
|
+
description: pkg.description
|
|
268
|
+
};
|
|
269
|
+
} catch {
|
|
270
|
+
return {
|
|
271
|
+
id: "com.example.app",
|
|
272
|
+
name: "Table App",
|
|
273
|
+
version: "1.0.0"
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
// src/builder.ts
|
|
280
|
+
async function build(platform, options = {}) {
|
|
281
|
+
const opts = {
|
|
282
|
+
platform,
|
|
283
|
+
outDir: options.outDir || "dist",
|
|
284
|
+
minify: options.minify ?? true,
|
|
285
|
+
sourcemap: options.sourcemap ?? false
|
|
286
|
+
};
|
|
287
|
+
if (platform === "all") {
|
|
288
|
+
await Promise.all([
|
|
289
|
+
buildPlatform("tizen", opts),
|
|
290
|
+
buildPlatform("webos", opts),
|
|
291
|
+
buildPlatform("android", opts)
|
|
292
|
+
]);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
await buildPlatform(platform, opts);
|
|
296
|
+
}
|
|
297
|
+
async function buildPlatform(platform, options) {
|
|
298
|
+
const adapter = getAdapter(platform);
|
|
299
|
+
await viteBuild({
|
|
300
|
+
build: {
|
|
301
|
+
outDir: `${options.outDir}/${platform}`,
|
|
302
|
+
minify: options.minify,
|
|
303
|
+
sourcemap: options.sourcemap,
|
|
304
|
+
emptyOutDir: true
|
|
305
|
+
},
|
|
306
|
+
define: {
|
|
307
|
+
__TABLE_PLATFORM__: JSON.stringify(platform)
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
await adapter.build(options);
|
|
311
|
+
const packagePath = await adapter.package(`${options.outDir}/${platform}`);
|
|
312
|
+
console.log(`\u2713 ${adapter.name} package created: ${packagePath}`);
|
|
313
|
+
}
|
|
314
|
+
function getAdapter(platform) {
|
|
315
|
+
switch (platform) {
|
|
316
|
+
case "tizen":
|
|
317
|
+
return new TizenAdapter();
|
|
318
|
+
case "webos":
|
|
319
|
+
return new WebOSAdapter();
|
|
320
|
+
case "android":
|
|
321
|
+
return new AndroidAdapter();
|
|
322
|
+
default:
|
|
323
|
+
throw new Error(`Unknown platform: ${platform}`);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
export {
|
|
327
|
+
AndroidAdapter,
|
|
328
|
+
TizenAdapter,
|
|
329
|
+
WebOSAdapter,
|
|
330
|
+
build
|
|
331
|
+
};
|
|
332
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/builder.ts","../src/adapters/tizen.ts","../src/adapters/webos.ts","../src/adapters/android.ts"],"sourcesContent":["import { build as viteBuild } from 'vite'\nimport type { BuildOptions, Platform, PlatformAdapter } from './types'\nimport { TizenAdapter } from './adapters/tizen'\nimport { WebOSAdapter } from './adapters/webos'\nimport { AndroidAdapter } from './adapters/android'\n\nexport async function build(platform: Platform, options: Partial<BuildOptions> = {}) {\n const opts: BuildOptions = {\n platform,\n outDir: options.outDir || 'dist',\n minify: options.minify ?? true,\n sourcemap: options.sourcemap ?? false,\n }\n\n if (platform === 'all') {\n await Promise.all([\n buildPlatform('tizen', opts),\n buildPlatform('webos', opts),\n buildPlatform('android', opts),\n ])\n return\n }\n\n await buildPlatform(platform, opts)\n}\n\nasync function buildPlatform(platform: Platform, options: BuildOptions) {\n const adapter = getAdapter(platform)\n\n await viteBuild({\n build: {\n outDir: `${options.outDir}/${platform}`,\n minify: options.minify,\n sourcemap: options.sourcemap,\n emptyOutDir: true,\n },\n define: {\n __TABLE_PLATFORM__: JSON.stringify(platform),\n },\n })\n\n await adapter.build(options)\n\n const packagePath = await adapter.package(`${options.outDir}/${platform}`)\n console.log(`✓ ${adapter.name} package created: ${packagePath}`)\n}\n\nfunction getAdapter(platform: Platform): PlatformAdapter {\n switch (platform) {\n case 'tizen':\n return new TizenAdapter()\n case 'webos':\n return new WebOSAdapter()\n case 'android':\n return new AndroidAdapter()\n default:\n throw new Error(`Unknown platform: ${platform}`)\n }\n}\n","import path from 'path'\nimport fs from 'fs-extra'\nimport archiver from 'archiver'\nimport { createWriteStream } from 'fs'\nimport type { BuildOptions, PlatformAdapter, ManifestBase } from '../types'\n\nexport class TizenAdapter implements PlatformAdapter {\n name = 'Tizen (Samsung)'\n\n async build(options: BuildOptions): Promise<void> {\n const distDir = `${options.outDir}/tizen`\n await this.createConfig(distDir)\n }\n\n async package(distDir: string): Promise<string> {\n const outputPath = path.join(distDir, '..', 'app.wgt')\n\n await new Promise<void>((resolve, reject) => {\n const output = createWriteStream(outputPath)\n const archive = archiver('zip', { zlib: { level: 9 } })\n\n output.on('close', () => resolve())\n archive.on('error', reject)\n\n archive.pipe(output)\n archive.directory(distDir, false)\n archive.finalize()\n })\n\n return outputPath\n }\n\n private async createConfig(distDir: string) {\n const pkg = await this.readPackageJson()\n\n const config = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<widget xmlns=\"http://www.w3.org/ns/widgets\" \n xmlns:tizen=\"http://tizen.org/ns/widgets\"\n id=\"${pkg.id || 'com.example.app'}\"\n version=\"${pkg.version}\"\n viewmodes=\"maximized\">\n <tizen:application id=\"${pkg.id || 'com.example.app'}.App\" \n package=\"${pkg.id || 'com.example.app'}\"\n required_version=\"6.0\"/>\n <content src=\"index.html\"/>\n <feature name=\"http://tizen.org/feature/screen.size.all\"/>\n <icon src=\"icon.png\"/>\n <name>${pkg.name}</name>\n <tizen:profile name=\"tv\"/>\n <tizen:setting screen-orientation=\"landscape\" \n context-menu=\"disable\" \n background-support=\"disable\" \n encryption=\"disable\" \n install-location=\"auto\"/>\n</widget>`\n\n await fs.writeFile(path.join(distDir, 'config.xml'), config)\n }\n\n private async readPackageJson(): Promise<ManifestBase> {\n try {\n const pkg = await fs.readJson('package.json')\n return {\n id: pkg.tizenAppId || pkg.name,\n name: pkg.name,\n version: pkg.version,\n description: pkg.description,\n }\n } catch {\n return {\n id: 'com.example.app',\n name: 'Table App',\n version: '1.0.0',\n }\n }\n }\n}\n","import path from 'path'\nimport fs from 'fs-extra'\nimport archiver from 'archiver'\nimport { createWriteStream } from 'fs'\nimport type { BuildOptions, PlatformAdapter, ManifestBase } from '../types'\n\nexport class WebOSAdapter implements PlatformAdapter {\n name = 'webOS (LG)'\n\n async build(options: BuildOptions): Promise<void> {\n const distDir = `${options.outDir}/webos`\n await this.createAppInfo(distDir)\n }\n\n async package(distDir: string): Promise<string> {\n const outputPath = path.join(distDir, '..', 'app.ipk')\n\n await new Promise<void>((resolve, reject) => {\n const output = createWriteStream(outputPath)\n const archive = archiver('tar', { gzip: true })\n\n output.on('close', () => resolve())\n archive.on('error', reject)\n\n archive.pipe(output)\n archive.directory(distDir, false)\n archive.finalize()\n })\n\n return outputPath\n }\n\n private async createAppInfo(distDir: string) {\n const pkg = await this.readPackageJson()\n\n const appInfo = {\n id: pkg.id || 'com.example.app',\n version: pkg.version,\n vendor: 'Table.js',\n type: 'web',\n main: 'index.html',\n title: pkg.name,\n icon: 'icon.png',\n largeIcon: 'icon.png',\n bgImage: 'splash.png',\n resolution: '1920x1080',\n disallowScrollingInMainWindow: true,\n }\n\n await fs.writeJson(path.join(distDir, 'appinfo.json'), appInfo, { spaces: 2 })\n }\n\n private async readPackageJson(): Promise<ManifestBase> {\n try {\n const pkg = await fs.readJson('package.json')\n return {\n id: pkg.webosAppId || pkg.name,\n name: pkg.name,\n version: pkg.version,\n description: pkg.description,\n }\n } catch {\n return {\n id: 'com.example.app',\n name: 'Table App',\n version: '1.0.0',\n }\n }\n }\n}\n","import path from 'path'\nimport fs from 'fs-extra'\nimport { execa } from 'execa'\nimport type { BuildOptions, PlatformAdapter, ManifestBase } from '../types'\n\nexport class AndroidAdapter implements PlatformAdapter {\n name = 'Android TV'\n\n async build(options: BuildOptions): Promise<void> {\n const distDir = `${options.outDir}/android`\n await this.createWebViewProject(distDir)\n }\n\n async package(distDir: string): Promise<string> {\n const projectDir = path.join(distDir, 'android-project')\n\n try {\n await execa('./gradlew', ['assembleRelease'], {\n cwd: projectDir,\n stdio: 'inherit',\n })\n\n const apkPath = path.join(projectDir, 'app/build/outputs/apk/release/app-release.apk')\n\n const outputPath = path.join(distDir, '..', 'app.apk')\n await fs.copy(apkPath, outputPath)\n\n return outputPath\n } catch (error) {\n throw new Error('Android build failed. Make sure Android SDK is installed.')\n }\n }\n\n private async createWebViewProject(distDir: string) {\n const pkg = await this.readPackageJson()\n const projectDir = path.join(distDir, 'android-project')\n\n await fs.ensureDir(projectDir)\n await fs.copy(distDir, path.join(projectDir, 'app/src/main/assets/www'))\n\n await this.createManifest(projectDir, pkg)\n await this.createGradleFiles(projectDir, pkg)\n await this.createMainActivity(projectDir, pkg)\n }\n\n private async createManifest(projectDir: string, pkg: ManifestBase) {\n const manifest = `<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package=\"${pkg.id || 'com.example.app'}\">\n\n <uses-permission android:name=\"android.permission.INTERNET\" />\n <uses-feature android:name=\"android.software.leanback\" android:required=\"true\" />\n <uses-feature android:name=\"android.hardware.touchscreen\" android:required=\"false\" />\n\n <application\n android:allowBackup=\"true\"\n android:icon=\"@mipmap/ic_launcher\"\n android:label=\"${pkg.name}\"\n android:banner=\"@drawable/banner\"\n android:theme=\"@style/Theme.Leanback\">\n \n <activity\n android:name=\".MainActivity\"\n android:exported=\"true\"\n android:screenOrientation=\"landscape\">\n <intent-filter>\n <action android:name=\"android.intent.action.MAIN\" />\n <category android:name=\"android.intent.category.LEANBACK_LAUNCHER\" />\n </intent-filter>\n </activity>\n </application>\n</manifest>`\n\n const manifestPath = path.join(projectDir, 'app/src/main/AndroidManifest.xml')\n await fs.ensureDir(path.dirname(manifestPath))\n await fs.writeFile(manifestPath, manifest)\n }\n\n private async createGradleFiles(projectDir: string, pkg: ManifestBase) {\n const buildGradle = `plugins {\n id 'com.android.application'\n}\n\nandroid {\n namespace '${pkg.id || 'com.example.app'}'\n compileSdk 34\n\n defaultConfig {\n applicationId \"${pkg.id || 'com.example.app'}\"\n minSdk 21\n targetSdk 34\n versionCode 1\n versionName \"${pkg.version}\"\n }\n\n buildTypes {\n release {\n minifyEnabled true\n proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')\n }\n }\n}\n\ndependencies {\n implementation 'androidx.leanback:leanback:1.0.0'\n}`\n\n await fs.writeFile(path.join(projectDir, 'app/build.gradle'), buildGradle)\n }\n\n private async createMainActivity(projectDir: string, pkg: ManifestBase) {\n const packageName = pkg.id || 'com.example.app'\n const activity = `package ${packageName};\n\nimport android.app.Activity;\nimport android.os.Bundle;\nimport android.webkit.WebView;\nimport android.webkit.WebSettings;\n\npublic class MainActivity extends Activity {\n private WebView webView;\n\n @Override\n protected void onCreate(Bundle savedInstanceState) {\n super.onCreate(savedInstanceState);\n \n webView = new WebView(this);\n setContentView(webView);\n \n WebSettings settings = webView.getSettings();\n settings.setJavaScriptEnabled(true);\n settings.setDomStorageEnabled(true);\n settings.setAllowFileAccess(true);\n \n webView.loadUrl(\"file:///android_asset/www/index.html\");\n }\n}`\n\n const activityPath = path.join(\n projectDir,\n `app/src/main/java/${packageName.replace(/\\./g, '/')}/MainActivity.java`,\n )\n await fs.ensureDir(path.dirname(activityPath))\n await fs.writeFile(activityPath, activity)\n }\n\n private async readPackageJson(): Promise<ManifestBase> {\n try {\n const pkg = await fs.readJson('package.json')\n return {\n id: pkg.androidAppId || pkg.name.replace(/[^a-z0-9]/gi, '.').toLowerCase(),\n name: pkg.name,\n version: pkg.version,\n description: pkg.description,\n }\n } catch {\n return {\n id: 'com.example.app',\n name: 'Table App',\n version: '1.0.0',\n }\n }\n }\n}\n"],"mappings":"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","names":["path","fs","archiver","createWriteStream","path","fs"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@table-js/platform",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Table.js platform adapters and build tools for Smart TV",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"table": "./dist/cli.mjs"
|
|
10
|
+
},
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/index.mjs",
|
|
14
|
+
"require": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsup",
|
|
23
|
+
"dev": "tsup --watch",
|
|
24
|
+
"typecheck": "tsc --noEmit",
|
|
25
|
+
"clean": "rm -rf dist"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"smart-tv",
|
|
29
|
+
"tizen",
|
|
30
|
+
"webos",
|
|
31
|
+
"android-tv",
|
|
32
|
+
"build-tool",
|
|
33
|
+
"vite"
|
|
34
|
+
],
|
|
35
|
+
"author": "Table.js Team",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "https://github.com/tablejs/tablejs"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"vite": "^6.4.1",
|
|
43
|
+
"chalk": "^5.6.2",
|
|
44
|
+
"commander": "^12.1.0",
|
|
45
|
+
"execa": "^8.0.1",
|
|
46
|
+
"fs-extra": "^11.3.4",
|
|
47
|
+
"archiver": "^7.0.1",
|
|
48
|
+
"ora": "^8.2.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@table/tsconfig": "workspace:*",
|
|
52
|
+
"@types/archiver": "^7.0.0",
|
|
53
|
+
"@types/fs-extra": "^11.0.4",
|
|
54
|
+
"@types/node": "^25.5.0",
|
|
55
|
+
"tsup": "^8.0.1",
|
|
56
|
+
"typescript": "^5.3.3"
|
|
57
|
+
}
|
|
58
|
+
}
|