@youcan/app 2.3.1 → 2.3.3

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.
@@ -1,6 +1,9 @@
1
1
  import { AppCommand } from '@/util/app-command';
2
2
  declare class Dev extends AppCommand {
3
3
  static description: string;
4
+ private workers;
5
+ constructor(argv: string[], config: any);
6
+ private setupExitHandlers;
4
7
  private readonly hotKeys;
5
8
  run(): Promise<any>;
6
9
  private prepareNetworkOptions;
@@ -1,11 +1,42 @@
1
- import { Session, Tasks, UI, System, Services, Filesystem, Path, Env, Http } from '@youcan/cli-kit';
1
+ import process from 'node:process';
2
2
  import { bootTunnelWorker, bootAppWorker, bootWebWorker, bootExtensionWorker } from '../../services/dev/workers/index.js';
3
+ import { APP_CONFIG_FILENAME } from '../../../constants.js';
3
4
  import { AppCommand } from '../../../util/app-command.js';
4
5
  import { load } from '../../../util/app-loader.js';
5
- import { APP_CONFIG_FILENAME } from '../../../constants.js';
6
+ import { Session, Tasks, UI, System, Services, Filesystem, Path, Env, Http } from '@youcan/cli-kit';
6
7
 
7
8
  class Dev extends AppCommand {
8
9
  static description = 'Run the app in dev mode';
10
+ workers = [];
11
+ constructor(argv, config) {
12
+ super(argv, config);
13
+ this.setupExitHandlers();
14
+ }
15
+ setupExitHandlers() {
16
+ const cleanupAndExit = () => {
17
+ try {
18
+ if (this.controller) {
19
+ this.controller.abort();
20
+ }
21
+ this.workers = [];
22
+ console.log('Shutting down...');
23
+ setTimeout(() => {
24
+ process.exit(0);
25
+ }, 100);
26
+ }
27
+ catch (error) {
28
+ process.exit(0);
29
+ }
30
+ };
31
+ process.once('SIGINT', cleanupAndExit);
32
+ process.once('SIGTERM', cleanupAndExit);
33
+ process.once('SIGQUIT', cleanupAndExit);
34
+ process.once('exit', () => {
35
+ if (this.controller) {
36
+ this.controller.abort();
37
+ }
38
+ });
39
+ }
9
40
  hotKeys = [
10
41
  {
11
42
  keyboardKey: 'p',
@@ -15,7 +46,21 @@ class Dev extends AppCommand {
15
46
  {
16
47
  keyboardKey: 'q',
17
48
  description: 'quit',
18
- handler: () => this.exit(0),
49
+ handler: () => {
50
+ try {
51
+ if (this.controller) {
52
+ this.controller.abort();
53
+ }
54
+ this.workers = [];
55
+ console.log('Shutting down...');
56
+ setTimeout(() => {
57
+ process.exit(0);
58
+ }, 100);
59
+ }
60
+ catch (error) {
61
+ process.exit(0);
62
+ }
63
+ },
19
64
  },
20
65
  ];
21
66
  async run() {
@@ -43,10 +88,10 @@ class Dev extends AppCommand {
43
88
  this.runWorkers(workers);
44
89
  }
45
90
  async prepareNetworkOptions() {
46
- const port = await System.getNextAvailablePort(3000);
91
+ const port = await System.getPortOrNextOrRandom(3000);
47
92
  this.app.network_config = {
48
93
  app_port: port,
49
- app_url: `http://localhost:${port}`
94
+ app_url: `http://localhost:${port}`,
50
95
  };
51
96
  const worker = await bootTunnelWorker(this, this.app, new Services.Cloudflared());
52
97
  this.app.config = {
@@ -54,14 +99,13 @@ class Dev extends AppCommand {
54
99
  app_url: worker.getUrl(),
55
100
  redirect_urls: this.app.config.redirect_urls?.length > 0
56
101
  ? this.app.config.redirect_urls.map(r => new URL(new URL(r).pathname, worker.getUrl()).toString())
57
- : [new URL('/auth/callback', worker.getUrl()).toString()]
102
+ : [new URL('/auth/callback', worker.getUrl()).toString()],
58
103
  };
59
104
  await Filesystem.writeJsonFile(Path.join(this.app.root, APP_CONFIG_FILENAME), this.app.config);
60
105
  return worker;
61
106
  }
62
107
  async reloadWorkers() {
63
108
  this.controller = new AbortController();
64
- // Preserve network config.
65
109
  const networkConfig = this.app.network_config;
66
110
  this.app = await load();
67
111
  this.app.network_config = networkConfig;
@@ -1,6 +1,6 @@
1
- import { Session, Tasks, Color } from '@youcan/cli-kit';
2
1
  import { AppCommand } from '../../../../util/app-command.js';
3
2
  import { load } from '../../../../util/app-loader.js';
3
+ import { Session, Tasks, Color } from '@youcan/cli-kit';
4
4
 
5
5
  class EnvShow extends AppCommand {
6
6
  static description = 'Display app environment variables';
@@ -1,8 +1,8 @@
1
- import { Path, Filesystem, String, Tasks } from '@youcan/cli-kit';
2
- import { AppCommand } from '../../../../util/app-command.js';
3
1
  import extensions from '../../../services/generate/extensions/index.js';
4
2
  import { ensureExtensionDirectoryExists, initThemeExtension } from '../../../services/generate/generate.js';
5
3
  import { APP_CONFIG_FILENAME } from '../../../../constants.js';
4
+ import { AppCommand } from '../../../../util/app-command.js';
5
+ import { Path, Filesystem, String, Tasks } from '@youcan/cli-kit';
6
6
 
7
7
  class GenerateExtension extends AppCommand {
8
8
  static description = 'Generate an app extension';
@@ -1,6 +1,6 @@
1
- import { Session, Tasks, Http, Env, System } from '@youcan/cli-kit';
2
- import { load } from '../../../util/app-loader.js';
3
1
  import { AppCommand } from '../../../util/app-command.js';
2
+ import { load } from '../../../util/app-loader.js';
3
+ import { Session, Tasks, Http, Env, System } from '@youcan/cli-kit';
4
4
 
5
5
  class Install extends AppCommand {
6
6
  static description = 'Generate an app installation URL';
@@ -1,6 +1,6 @@
1
- import { Worker } from '@youcan/cli-kit';
2
- import type { App } from '@/types';
3
1
  import type DevCommand from '@/cli/commands/app/dev';
2
+ import type { App } from '@/types';
3
+ import { Worker } from '@youcan/cli-kit';
4
4
  export default class AppWorker extends Worker.Abstract {
5
5
  private command;
6
6
  private app;
@@ -1,5 +1,5 @@
1
- import { Worker, Filesystem, Path } from '@youcan/cli-kit';
2
1
  import { APP_CONFIG_FILENAME } from '../../../../constants.js';
2
+ import { Worker, Filesystem, Path } from '@youcan/cli-kit';
3
3
 
4
4
  class AppWorker extends Worker.Abstract {
5
5
  command;
@@ -1,10 +1,10 @@
1
+ import type DevCommand from '@/cli/commands/app/dev';
2
+ import type { App, Extension, Web } from '@/types';
3
+ import type { AppCommand } from '@/util/app-command';
1
4
  import type { Cli, Services, Worker } from '@youcan/cli-kit';
2
- import WebWorker from './web-worker';
3
5
  import AppWorker from './app-worker';
4
6
  import TunnelWorker from './tunnel-worker';
5
- import type { App, Extension, Web } from '@/types';
6
- import type DevCommand from '@/cli/commands/app/dev';
7
- import type { AppCommand } from '@/util/app-command';
7
+ import WebWorker from './web-worker';
8
8
  export interface ExtensionWorkerCtor {
9
9
  new (command: Cli.Command, app: App, extension: Extension): Worker.Interface;
10
10
  }
@@ -1,7 +1,7 @@
1
- import ThemeExtensionWorker from './theme-extension-worker.js';
2
- import WebWorker from './web-worker.js';
3
1
  import AppWorker from './app-worker.js';
2
+ import ThemeExtensionWorker from './theme-extension-worker.js';
4
3
  import TunnelWorker from './tunnel-worker.js';
4
+ import WebWorker from './web-worker.js';
5
5
 
6
6
  const EXTENSION_WORKERS = {
7
7
  theme: ThemeExtensionWorker,
@@ -1,6 +1,6 @@
1
+ import type { App, Extension } from '@/types';
1
2
  import type { Cli } from '@youcan/cli-kit';
2
3
  import { Worker } from '@youcan/cli-kit';
3
- import type { App, Extension } from '@/types';
4
4
  export default class ThemeExtensionWorker extends Worker.Abstract {
5
5
  private command;
6
6
  private app;
@@ -1,7 +1,7 @@
1
- import { Worker } from '@youcan/cli-kit';
2
- import type { Services } from '@youcan/cli-kit';
3
1
  import type { App } from '@/types';
4
2
  import type { AppCommand } from '@/util/app-command';
3
+ import type { Services } from '@youcan/cli-kit';
4
+ import { Worker } from '@youcan/cli-kit';
5
5
  export default class TunnelWorker extends Worker.Abstract {
6
6
  private command;
7
7
  private app;
@@ -27,6 +27,7 @@ class TunnelWorker extends Worker.Abstract {
27
27
  this.app.network_config.app_url = this.url;
28
28
  this.logger.write(`tunneled url obtained: \`${url}\``);
29
29
  }
30
+ attempts++;
30
31
  await System.sleep(0.5);
31
32
  }
32
33
  if (!this.url) {
@@ -1,5 +1,5 @@
1
- import { type Cli, Worker } from '@youcan/cli-kit';
2
1
  import type { App, Web } from '@/types';
2
+ import { type Cli, Worker } from '@youcan/cli-kit';
3
3
  export default class WebWorker extends Worker.Abstract {
4
4
  private readonly command;
5
5
  private readonly app;
@@ -1,5 +1,5 @@
1
- import { Path, Filesystem, Git } from '@youcan/cli-kit';
2
1
  import { EXTENSION_CONFIG_FILENAME } from '../../../constants.js';
2
+ import { Path, Filesystem, Git } from '@youcan/cli-kit';
3
3
 
4
4
  async function ensureExtensionDirectoryExists(name) {
5
5
  const dir = Path.join(Path.cwd(), 'extensions', name);
@@ -1,6 +1,6 @@
1
+ import type { App } from '@/types';
1
2
  import type { Session } from '@youcan/cli-kit';
2
3
  import { Cli } from '@youcan/cli-kit';
3
- import type { App } from '@/types';
4
4
  export declare abstract class AppCommand extends Cli.Command {
5
5
  protected app: App;
6
6
  protected session: Session.StoreSession;
@@ -1,5 +1,5 @@
1
- import { Cli, Env, Http, Filesystem, Path } from '@youcan/cli-kit';
2
1
  import { APP_CONFIG_FILENAME } from '../constants.js';
2
+ import { Cli, Env, Http, Filesystem, Path } from '@youcan/cli-kit';
3
3
 
4
4
  class AppCommand extends Cli.Command {
5
5
  app;
@@ -13,7 +13,7 @@ class AppCommand extends Cli.Command {
13
13
  body: JSON.stringify({
14
14
  name: this.app.config.name,
15
15
  app_url: this.app.config.app_url,
16
- redirect_urls: this.app.config.redirect_urls
16
+ redirect_urls: this.app.config.redirect_urls,
17
17
  }),
18
18
  });
19
19
  this.app.config = {
@@ -1,5 +1,5 @@
1
- import { Path, Filesystem } from '@youcan/cli-kit';
2
1
  import { APP_CONFIG_FILENAME, DEFAULT_EXTENSIONS_DIR, EXTENSION_CONFIG_FILENAME, DEFAULT_WEBS_DIR, WEB_CONFIG_FILENAME } from '../constants.js';
2
+ import { Path, Filesystem } from '@youcan/cli-kit';
3
3
 
4
4
  async function load() {
5
5
  const path = Path.resolve(Path.cwd(), APP_CONFIG_FILENAME);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@youcan/app",
3
3
  "type": "module",
4
- "version": "2.3.1",
4
+ "version": "2.3.3",
5
5
  "description": "OCLIF plugin for building apps",
6
6
  "author": "YouCan <contact@youcan.shop> (https://youcan.shop)",
7
7
  "license": "MIT",
@@ -17,7 +17,7 @@
17
17
  "dependencies": {
18
18
  "@oclif/core": "^2.15.0",
19
19
  "dayjs": "^1.11.10",
20
- "@youcan/cli-kit": "2.3.1"
20
+ "@youcan/cli-kit": "2.3.3"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@oclif/plugin-legacy": "^1.3.0",