@telemetryos/cli 1.7.0 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # @telemetryos/cli
2
2
 
3
+ ## 1.7.1
4
+
5
+ ### Patch Changes
6
+
7
+ - do not write workers to public dir
8
+ - Updated dependencies
9
+ - @telemetryos/development-application-host-ui@1.7.1
10
+
3
11
  ## 1.7.0
4
12
 
5
13
  ### Minor Changes
@@ -0,0 +1,10 @@
1
+ export type GenerateApplicationOptions = {
2
+ name: string;
3
+ description: string;
4
+ author: string;
5
+ version: string;
6
+ template: string;
7
+ projectPath: string;
8
+ progressFn: (createdFilePath: string) => void;
9
+ };
10
+ export declare function generateApplication(options: GenerateApplicationOptions): Promise<void>;
@@ -0,0 +1,45 @@
1
+ import fs from "fs/promises";
2
+ import path from "path";
3
+ const ignoredTelemplateFiles = [
4
+ '.DS_Store',
5
+ 'thumbs.db',
6
+ 'node_modules',
7
+ '.git',
8
+ 'dist'
9
+ ];
10
+ const templatesDir = path.join(import.meta.dirname, '../templates');
11
+ export async function generateApplication(options) {
12
+ const { name, description, author, version, template, projectPath, progressFn } = options;
13
+ await fs.mkdir(projectPath, { recursive: true });
14
+ await copyDir(path.join(templatesDir, template), projectPath, {
15
+ name,
16
+ description,
17
+ author,
18
+ version
19
+ }, progressFn);
20
+ }
21
+ async function copyDir(source, destination, replacements, progressFn) {
22
+ const dirListing = await fs.readdir(source);
23
+ for (const dirEntry of dirListing) {
24
+ if (ignoredTelemplateFiles.includes(dirEntry))
25
+ continue;
26
+ const sourcePath = path.join(source, dirEntry);
27
+ const destinationPath = path.join(destination, dirEntry);
28
+ const stats = await fs.stat(sourcePath);
29
+ if (stats.isDirectory()) {
30
+ await fs.mkdir(destinationPath, { recursive: true });
31
+ await copyDir(sourcePath, destinationPath, replacements, progressFn);
32
+ }
33
+ else if (stats.isFile()) {
34
+ await copyFile(sourcePath, destinationPath, replacements, progressFn);
35
+ }
36
+ }
37
+ }
38
+ async function copyFile(source, destination, replacements, progressFn) {
39
+ let contents = await fs.readFile(source, 'utf-8');
40
+ for (const [key, value] of Object.entries(replacements)) {
41
+ contents = contents.replace(new RegExp(`{{${key}}}`, 'g'), value);
42
+ }
43
+ await fs.writeFile(destination, contents, 'utf-8');
44
+ progressFn(destination);
45
+ }
@@ -0,0 +1,5 @@
1
+ type Flags = {
2
+ port: number;
3
+ };
4
+ export declare function runServer(projectPath: string, flags: Flags): Promise<void>;
5
+ export {};
@@ -0,0 +1,104 @@
1
+ import { spawn } from 'child_process';
2
+ import { readFile } from 'fs/promises';
3
+ import http from 'http';
4
+ import path from 'path';
5
+ import readable from 'readline/promises';
6
+ import serveHandler from 'serve-handler';
7
+ const ansiYellow = '\u001b[33m';
8
+ const ansiCyan = '\u001b[36m';
9
+ const ansiBold = '\u001b[1m';
10
+ const ansiReset = '\u001b[0m';
11
+ export async function runServer(projectPath, flags) {
12
+ printSplashScreen();
13
+ projectPath = path.resolve(process.cwd(), projectPath);
14
+ const telemetryConfig = await loadConfigFile(projectPath);
15
+ if (!telemetryConfig) {
16
+ console.error('No telemetry configuration found. Are you in the right directory?');
17
+ process.exit(1);
18
+ }
19
+ await serveDevelopmentApplicationHostUI(flags.port, telemetryConfig);
20
+ await serveTelemetryApplication(projectPath, telemetryConfig);
21
+ }
22
+ async function serveDevelopmentApplicationHostUI(port, telemetryConfig) {
23
+ const hostUiPath = await import.meta.resolve('@telemetryos/development-application-host-ui/dist');
24
+ const serveConfig = { public: hostUiPath.replace('file://', '') };
25
+ const server = http.createServer();
26
+ server.on('request', (req, res) => {
27
+ const url = new URL(req.url, `http://${req.headers.origin}`);
28
+ if (url.pathname === '/__tos-config__') {
29
+ res.setHeader('Content-Type', 'application/json');
30
+ res.end(JSON.stringify(telemetryConfig));
31
+ return;
32
+ }
33
+ serveHandler(req, res, serveConfig).catch((err) => {
34
+ console.error('Error handling request:', err);
35
+ res.statusCode = 500;
36
+ res.end('Internal Server Error');
37
+ });
38
+ });
39
+ printServerInfo(port);
40
+ server.listen(port);
41
+ }
42
+ async function serveTelemetryApplication(rootPath, telemetryConfig) {
43
+ var _a;
44
+ if (!((_a = telemetryConfig === null || telemetryConfig === void 0 ? void 0 : telemetryConfig.devServer) === null || _a === void 0 ? void 0 : _a.runCommand))
45
+ return;
46
+ const runCommand = telemetryConfig.devServer.runCommand;
47
+ const binPath = path.join(rootPath, 'node_modules', '.bin');
48
+ const childProcess = spawn(runCommand, {
49
+ shell: true,
50
+ env: { ...process.env, FORCE_COLOR: '1', PATH: `${binPath}:${process.env.PATH}` },
51
+ stdio: ['ignore', 'pipe', 'pipe'],
52
+ cwd: rootPath,
53
+ });
54
+ const stdoutReadline = readable.createInterface({
55
+ input: childProcess.stdout,
56
+ crlfDelay: Infinity,
57
+ });
58
+ const stderrReadline = readable.createInterface({
59
+ input: childProcess.stderr,
60
+ crlfDelay: Infinity,
61
+ });
62
+ stdoutReadline.on('line', (line) => {
63
+ console.log(`[application]: ${line}`);
64
+ });
65
+ stderrReadline.on('line', (line) => {
66
+ console.error(`[application]: ${line}`);
67
+ });
68
+ process.on('exit', () => {
69
+ childProcess.kill();
70
+ });
71
+ }
72
+ async function loadConfigFile(rootPath) {
73
+ const configFilePath = path.join(rootPath, 'telemetry.config.json');
74
+ try {
75
+ const fileContent = await readFile(configFilePath, 'utf-8');
76
+ const config = JSON.parse(fileContent);
77
+ return config;
78
+ }
79
+ catch {
80
+ return null;
81
+ }
82
+ }
83
+ function printSplashScreen() {
84
+ console.log(`${ansiYellow}
85
+ ▄ ▄
86
+ █ █ ▄▀▐
87
+ █ █ █ ▄▀ ▐
88
+ █ █ █ █ █ █ █ ▀ ▄▀
89
+ █ █ █ █ ▛ ▄ █ ▀
90
+ ▀█▀ ▄▀▀▄ █ ▄▀▀▄ █▀▄▀▄ ▄▀▀▄ ▀█▀ █▄▀ █ █ ▄▀ █ █
91
+ █ █▀▀▀ █ █▀▀▀ █ █ █ █▀▀▀ █ █ █ █ ▄▀ █ █ █
92
+ ▀▄ ▀▄▄▀ █ ▀▄▄▀ █ █ █ ▀▄▄▀ ▀▄ █ █ ▄▀ ▄▀ ▀ █ █ █
93
+ ▄▀ ▌ ▄▀ ▀ █ █
94
+ ▌▄▀ ▀ █
95
+ ▀ ▀
96
+ ${ansiReset}`);
97
+ }
98
+ function printServerInfo(port) {
99
+ console.log(`
100
+ ╔═══════════════════════════════════════════════════════════╗
101
+ ║ ${ansiBold}Development environment running at: ${ansiCyan}http://localhost:${port}${ansiReset} ║
102
+ ╚═══════════════════════════════════════════════════════════╝
103
+ `);
104
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telemetryos/cli",
3
- "version": "1.7.0",
3
+ "version": "1.7.1",
4
4
  "description": "The official TelemetryOS application CLI package. Use it to build applications that run on the TelemetryOS platform",
5
5
  "type": "module",
6
6
  "bin": {
@@ -25,7 +25,7 @@
25
25
  "license": "",
26
26
  "repository": "github:TelemetryTV/Application-API",
27
27
  "dependencies": {
28
- "@telemetryos/development-application-host-ui": "^1.7.0",
28
+ "@telemetryos/development-application-host-ui": "^1.7.1",
29
29
  "@types/serve-handler": "^6.1.4",
30
30
  "commander": "^14.0.0",
31
31
  "inquirer": "^12.9.6",