@youcan/app 1.1.0-beta.10 → 1.1.0-beta.12
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/dist/cli/commands/app/dev.js +8 -6
- package/dist/cli/services/dev/workers/abstract-worker.d.ts +16 -0
- package/dist/cli/services/dev/workers/abstract-worker.js +36 -0
- package/dist/cli/services/dev/workers/index.d.ts +11 -2
- package/dist/cli/services/dev/workers/index.js +7 -1
- package/dist/cli/services/dev/workers/theme-extension-worker.d.ts +4 -5
- package/dist/cli/services/dev/workers/theme-extension-worker.js +28 -43
- package/dist/cli/services/dev/workers/web-worker.d.ts +12 -0
- package/dist/cli/services/dev/workers/web-worker.js +27 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +3 -1
- package/dist/types.d.ts +13 -8
- package/dist/util/app-loader.js +17 -3
- package/package.json +2 -2
|
@@ -2,13 +2,13 @@ import { Session, Tasks, Env, Http, Filesystem, Path } from '@youcan/cli-kit';
|
|
|
2
2
|
import { AppCommand } from '../../../util/theme-command.js';
|
|
3
3
|
import { load } from '../../../util/app-loader.js';
|
|
4
4
|
import { APP_CONFIG_FILENAME } from '../../../constants.js';
|
|
5
|
-
import { bootExtensionWorker } from '../../services/dev/workers/index.js';
|
|
5
|
+
import { bootWebWorker, bootExtensionWorker } from '../../services/dev/workers/index.js';
|
|
6
6
|
|
|
7
7
|
class Dev extends AppCommand {
|
|
8
8
|
async run() {
|
|
9
9
|
const app = await load();
|
|
10
10
|
const session = await Session.authenticate(this);
|
|
11
|
-
await Tasks.run({ cmd: this }, [
|
|
11
|
+
const { workers } = await Tasks.run({ cmd: this, workers: [] }, [
|
|
12
12
|
{
|
|
13
13
|
title: 'Syncing app configuration..',
|
|
14
14
|
async task() {
|
|
@@ -37,14 +37,16 @@ class Dev extends AppCommand {
|
|
|
37
37
|
},
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
|
-
title: 'Preparing dev
|
|
40
|
+
title: 'Preparing dev processes...',
|
|
41
41
|
async task(ctx) {
|
|
42
|
-
const promises =
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
const promises = [];
|
|
43
|
+
app.webs.forEach(web => promises.unshift(bootWebWorker(ctx.cmd, app, web)));
|
|
44
|
+
app.extensions.forEach(ext => promises.unshift(bootExtensionWorker(ctx.cmd, app, ext)));
|
|
45
|
+
ctx.workers = await Promise.all(promises);
|
|
45
46
|
},
|
|
46
47
|
},
|
|
47
48
|
]);
|
|
49
|
+
await Promise.all(workers.map(async (worker) => await worker.run()));
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
52
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Writable } from 'stream';
|
|
3
|
+
import type { Color } from '@youcan/cli-kit';
|
|
4
|
+
import type { Worker } from './index';
|
|
5
|
+
export declare class WorkerLogger extends Writable {
|
|
6
|
+
private channel;
|
|
7
|
+
private type;
|
|
8
|
+
private color;
|
|
9
|
+
constructor(channel: 'stdout' | 'stderr', type: string, color: Color.Color);
|
|
10
|
+
write(chunk: unknown): boolean;
|
|
11
|
+
private center;
|
|
12
|
+
}
|
|
13
|
+
export default abstract class AbstractWorker implements Worker {
|
|
14
|
+
abstract boot(): Promise<void>;
|
|
15
|
+
abstract run(): Promise<void>;
|
|
16
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Writable } from 'node:stream';
|
|
2
|
+
import { stdout, stderr } from 'node:process';
|
|
3
|
+
import dayjs from 'dayjs';
|
|
4
|
+
|
|
5
|
+
class WorkerLogger extends Writable {
|
|
6
|
+
channel;
|
|
7
|
+
type;
|
|
8
|
+
color;
|
|
9
|
+
constructor(channel, type, color) {
|
|
10
|
+
super();
|
|
11
|
+
this.channel = channel;
|
|
12
|
+
this.type = type;
|
|
13
|
+
this.color = color;
|
|
14
|
+
}
|
|
15
|
+
write(chunk) {
|
|
16
|
+
if (!(chunk instanceof Buffer) && typeof chunk !== 'string') {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const channel = this.channel === 'stdout' ? stdout : stderr;
|
|
20
|
+
const time = dayjs().format('HH:mm:SSS');
|
|
21
|
+
const lines = chunk.toString().split('\n').map(s => s.trim()).filter(s => s !== '');
|
|
22
|
+
for (let i = 0; i < lines.length; i++) {
|
|
23
|
+
i === 0
|
|
24
|
+
? channel.write(this.color(`${time} [ ${this.center(this.type, 10)} ] ${lines[i]}\n`))
|
|
25
|
+
: channel.write(this.color(` ${lines[i]}\n`));
|
|
26
|
+
}
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
center(subject, length, char = ' ') {
|
|
30
|
+
return subject.padStart((subject.length + length) / 2, char).padEnd(length, char);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
class AbstractWorker {
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { WorkerLogger, AbstractWorker as default };
|
|
@@ -1,3 +1,12 @@
|
|
|
1
1
|
import type { Cli } from '@youcan/cli-kit';
|
|
2
|
-
import
|
|
3
|
-
|
|
2
|
+
import WebWorker from './web-worker';
|
|
3
|
+
import type { App, Extension, Web } from '@/types';
|
|
4
|
+
export interface ExtensionWorkerCtor {
|
|
5
|
+
new (command: Cli.Command, app: App, extension: Extension): Worker;
|
|
6
|
+
}
|
|
7
|
+
export interface Worker {
|
|
8
|
+
run(): Promise<void>;
|
|
9
|
+
boot(): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
export declare function bootExtensionWorker(command: Cli.Command, app: App, extension: Extension): Promise<Worker>;
|
|
12
|
+
export declare function bootWebWorker(command: Cli.Command, app: App, web: Web): Promise<WebWorker>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import ThemeExtensionWorker from './theme-extension-worker.js';
|
|
2
|
+
import WebWorker from './web-worker.js';
|
|
2
3
|
|
|
3
4
|
const EXTENSION_WORKERS = {
|
|
4
5
|
theme: ThemeExtensionWorker,
|
|
@@ -8,6 +9,11 @@ async function bootExtensionWorker(command, app, extension) {
|
|
|
8
9
|
const worker = new Ctor(command, app, extension);
|
|
9
10
|
await worker.boot();
|
|
10
11
|
return worker;
|
|
12
|
+
}
|
|
13
|
+
async function bootWebWorker(command, app, web) {
|
|
14
|
+
const worker = new WebWorker(command, app, web);
|
|
15
|
+
await worker.boot();
|
|
16
|
+
return worker;
|
|
11
17
|
}
|
|
12
18
|
|
|
13
|
-
export { bootExtensionWorker };
|
|
19
|
+
export { bootExtensionWorker, bootWebWorker };
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import type { Cli } from '@youcan/cli-kit';
|
|
2
|
-
import
|
|
3
|
-
|
|
2
|
+
import AbstractWorker from './abstract-worker';
|
|
3
|
+
import type { App, Extension } from '@/types';
|
|
4
|
+
export default class ThemeExtensionWorker extends AbstractWorker {
|
|
4
5
|
private command;
|
|
5
6
|
private app;
|
|
6
7
|
private extension;
|
|
8
|
+
private logger;
|
|
7
9
|
FILE_TYPES: string[];
|
|
8
|
-
private EVENT_LOG_MAP;
|
|
9
|
-
private formatter;
|
|
10
10
|
constructor(command: Cli.Command, app: App, extension: Extension);
|
|
11
11
|
boot(): Promise<void>;
|
|
12
12
|
run(): Promise<void>;
|
|
13
13
|
private file;
|
|
14
|
-
private log;
|
|
15
14
|
}
|
|
@@ -1,31 +1,23 @@
|
|
|
1
1
|
import { Color, Session, Http, Env, Path, Filesystem, Crypto, Form } from '@youcan/cli-kit';
|
|
2
|
+
import AbstractWorker, { WorkerLogger } from './abstract-worker.js';
|
|
2
3
|
|
|
3
|
-
class ThemeExtensionWorker {
|
|
4
|
+
class ThemeExtensionWorker extends AbstractWorker {
|
|
4
5
|
command;
|
|
5
6
|
app;
|
|
6
7
|
extension;
|
|
8
|
+
logger;
|
|
7
9
|
FILE_TYPES = [
|
|
8
10
|
'assets',
|
|
9
11
|
'locales',
|
|
10
12
|
'snippets',
|
|
11
13
|
'blocks',
|
|
12
14
|
];
|
|
13
|
-
EVENT_LOG_MAP = {
|
|
14
|
-
error: () => Color.bold().red('[error]'),
|
|
15
|
-
add: () => Color.bold().green('[created]'),
|
|
16
|
-
change: () => Color.bold().blue('[updated]'),
|
|
17
|
-
unlink: () => Color.bold().yellow('[deleted]'),
|
|
18
|
-
};
|
|
19
|
-
formatter = Intl.NumberFormat('en', {
|
|
20
|
-
unitDisplay: 'narrow',
|
|
21
|
-
notation: 'compact',
|
|
22
|
-
style: 'unit',
|
|
23
|
-
unit: 'byte',
|
|
24
|
-
});
|
|
25
15
|
constructor(command, app, extension) {
|
|
16
|
+
super();
|
|
26
17
|
this.command = command;
|
|
27
18
|
this.app = app;
|
|
28
19
|
this.extension = extension;
|
|
20
|
+
this.logger = new WorkerLogger('stdout', 'extensions', Color.yellow);
|
|
29
21
|
}
|
|
30
22
|
async boot() {
|
|
31
23
|
const session = await Session.authenticate(this.command);
|
|
@@ -36,29 +28,30 @@ class ThemeExtensionWorker {
|
|
|
36
28
|
});
|
|
37
29
|
this.extension.id = res.id;
|
|
38
30
|
this.extension.metadata = res.metadata;
|
|
39
|
-
for (const type of Object.keys(this.extension.metadata)) {
|
|
40
|
-
const descriptors = this.extension.metadata[type];
|
|
41
|
-
const directory = Path.resolve(this.extension.root, type);
|
|
42
|
-
const present = await Filesystem.readdir(Path.resolve(directory));
|
|
43
|
-
present.filter(f => !descriptors.find(d => d.file_name === f))
|
|
44
|
-
.forEach(async (file) => await this.file('put', type, file));
|
|
45
|
-
descriptors.forEach(async (descriptor) => {
|
|
46
|
-
const path = Path.resolve(directory, descriptor.file_name);
|
|
47
|
-
if (!(await Filesystem.exists(path))) {
|
|
48
|
-
return await this.file('del', type, descriptor.file_name);
|
|
49
|
-
}
|
|
50
|
-
const buff = await Filesystem.readFile(path);
|
|
51
|
-
if (Crypto.sha1(buff) !== descriptor.hash) {
|
|
52
|
-
await this.file('put', type, descriptor.file_name);
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
31
|
}
|
|
57
32
|
catch (err) {
|
|
58
33
|
this.command.error(err);
|
|
59
34
|
}
|
|
60
35
|
}
|
|
61
36
|
async run() {
|
|
37
|
+
this.logger.write(`pushed '${this.extension.config.name}' to a draft...`);
|
|
38
|
+
for (const type of Object.keys(this.extension.metadata)) {
|
|
39
|
+
const descriptors = this.extension.metadata[type];
|
|
40
|
+
const directory = Path.resolve(this.extension.root, type);
|
|
41
|
+
const present = await Filesystem.readdir(Path.resolve(directory));
|
|
42
|
+
present.filter(f => !descriptors.find(d => d.file_name === f))
|
|
43
|
+
.forEach(async (file) => await this.file('put', type, file));
|
|
44
|
+
descriptors.forEach(async (descriptor) => {
|
|
45
|
+
const path = Path.resolve(directory, descriptor.file_name);
|
|
46
|
+
if (!(await Filesystem.exists(path))) {
|
|
47
|
+
return await this.file('del', type, descriptor.file_name);
|
|
48
|
+
}
|
|
49
|
+
const buff = await Filesystem.readFile(path);
|
|
50
|
+
if (Crypto.sha1(buff) !== descriptor.hash) {
|
|
51
|
+
await this.file('put', type, descriptor.file_name);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
62
55
|
const paths = this.FILE_TYPES
|
|
63
56
|
.map(p => Path.resolve(this.extension.root, p));
|
|
64
57
|
const watcher = Filesystem.watch(paths, {
|
|
@@ -68,36 +61,33 @@ class ThemeExtensionWorker {
|
|
|
68
61
|
stabilityThreshold: 50,
|
|
69
62
|
},
|
|
70
63
|
});
|
|
71
|
-
watcher.on('all', async (event, path
|
|
64
|
+
watcher.on('all', async (event, path) => {
|
|
72
65
|
try {
|
|
73
66
|
if (!['add', 'change', 'unlink'].includes(event)) {
|
|
74
67
|
return;
|
|
75
68
|
}
|
|
76
|
-
const start = new Date().getTime();
|
|
77
69
|
const [filetype, filename] = [
|
|
78
70
|
Path.basename(Path.dirname(path)),
|
|
79
71
|
Path.basename(path),
|
|
80
72
|
];
|
|
81
|
-
let size = 0;
|
|
82
73
|
switch (event) {
|
|
83
74
|
case 'add':
|
|
84
75
|
case 'change':
|
|
85
|
-
|
|
76
|
+
await this.file('put', filetype, filename);
|
|
86
77
|
break;
|
|
87
78
|
case 'unlink':
|
|
88
|
-
|
|
79
|
+
await this.file('del', filetype, filename);
|
|
89
80
|
break;
|
|
90
81
|
}
|
|
91
|
-
this.log(event, Path.join(filetype, filename), this.formatter.format(stat.size), new Date().getTime() - start);
|
|
92
82
|
}
|
|
93
83
|
catch (err) {
|
|
94
|
-
this.
|
|
95
|
-
this.command.error(err);
|
|
84
|
+
this.command.output.warn(err);
|
|
96
85
|
}
|
|
97
86
|
});
|
|
98
87
|
}
|
|
99
88
|
async file(op, type, name) {
|
|
100
89
|
const path = Path.resolve(this.extension.root, type, name);
|
|
90
|
+
this.logger.write(`- ${Path.join(type, name)}`);
|
|
101
91
|
return await Http.post(`${Env.apiHostname()}/apps/draft/${this.app.config.id}/extensions/${this.extension.id}/file`, {
|
|
102
92
|
body: Form.convert({
|
|
103
93
|
file_name: name,
|
|
@@ -107,11 +97,6 @@ class ThemeExtensionWorker {
|
|
|
107
97
|
}),
|
|
108
98
|
});
|
|
109
99
|
}
|
|
110
|
-
log(event, path, size, time) {
|
|
111
|
-
const tag = this.EVENT_LOG_MAP[event]();
|
|
112
|
-
`${tag} ${Color.underline().white(path)}`;
|
|
113
|
-
this.command.log(`${tag} ${Color.underline().white(path)} - ${size} | ${time}ms \n`);
|
|
114
|
-
}
|
|
115
100
|
}
|
|
116
101
|
|
|
117
102
|
export { ThemeExtensionWorker as default };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Cli } from '@youcan/cli-kit';
|
|
2
|
+
import AbstractWorker from './abstract-worker';
|
|
3
|
+
import type { App, Web } from '@/types';
|
|
4
|
+
export default class WebWorker extends AbstractWorker {
|
|
5
|
+
private command;
|
|
6
|
+
private app;
|
|
7
|
+
private web;
|
|
8
|
+
private logger;
|
|
9
|
+
constructor(command: Cli.Command, app: App, web: Web);
|
|
10
|
+
boot(): Promise<void>;
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Color, System } from '@youcan/cli-kit';
|
|
2
|
+
import AbstractWorker, { WorkerLogger } from './abstract-worker.js';
|
|
3
|
+
|
|
4
|
+
class WebWorker extends AbstractWorker {
|
|
5
|
+
command;
|
|
6
|
+
app;
|
|
7
|
+
web;
|
|
8
|
+
logger;
|
|
9
|
+
constructor(command, app, web) {
|
|
10
|
+
super();
|
|
11
|
+
this.command = command;
|
|
12
|
+
this.app = app;
|
|
13
|
+
this.web = web;
|
|
14
|
+
this.logger = new WorkerLogger('stderr', this.web.config.name || 'web', Color.blue);
|
|
15
|
+
}
|
|
16
|
+
async boot() {
|
|
17
|
+
}
|
|
18
|
+
async run() {
|
|
19
|
+
const [cmd, ...args] = this.web.config.commands.dev.split(' ');
|
|
20
|
+
return System.exec(cmd, args, {
|
|
21
|
+
stdout: this.logger,
|
|
22
|
+
stderr: new WorkerLogger('stderr', this.web.config.name || 'web', Color.red),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export { WebWorker as default };
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export declare const APP_CONFIG_FILENAME = "youcan.app.json";
|
|
2
|
+
export declare const WEB_CONFIG_FILENAME = "youcan.web.json";
|
|
2
3
|
export declare const EXTENSION_CONFIG_FILENAME = "youcan.extension.json";
|
|
4
|
+
export declare const DEFAULT_WEBS_DIR = ".";
|
|
3
5
|
export declare const DEFAULT_EXTENSIONS_DIR = "extensions/";
|
package/dist/constants.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const APP_CONFIG_FILENAME = 'youcan.app.json';
|
|
2
|
+
const WEB_CONFIG_FILENAME = 'youcan.web.json';
|
|
2
3
|
const EXTENSION_CONFIG_FILENAME = 'youcan.extension.json';
|
|
4
|
+
const DEFAULT_WEBS_DIR = '.';
|
|
3
5
|
const DEFAULT_EXTENSIONS_DIR = 'extensions/';
|
|
4
6
|
|
|
5
|
-
export { APP_CONFIG_FILENAME, DEFAULT_EXTENSIONS_DIR, EXTENSION_CONFIG_FILENAME };
|
|
7
|
+
export { APP_CONFIG_FILENAME, DEFAULT_EXTENSIONS_DIR, DEFAULT_WEBS_DIR, EXTENSION_CONFIG_FILENAME, WEB_CONFIG_FILENAME };
|
package/dist/types.d.ts
CHANGED
|
@@ -1,15 +1,7 @@
|
|
|
1
|
-
import type { Cli } from '@youcan/cli-kit';
|
|
2
1
|
export interface InitialAppConfig {
|
|
3
2
|
[key: string]: unknown;
|
|
4
3
|
name: string;
|
|
5
4
|
}
|
|
6
|
-
export interface ExtensionWorkerConstructor<T extends Extension = Extension> {
|
|
7
|
-
new (command: Cli.Command, app: App, extension: T): ExtensionWorker;
|
|
8
|
-
}
|
|
9
|
-
export interface ExtensionWorker {
|
|
10
|
-
run(): Promise<void>;
|
|
11
|
-
boot(): Promise<void>;
|
|
12
|
-
}
|
|
13
5
|
export type AppConfig = {
|
|
14
6
|
id: string;
|
|
15
7
|
app_url: string;
|
|
@@ -46,8 +38,21 @@ export interface Extension {
|
|
|
46
38
|
root: string;
|
|
47
39
|
config: ExtensionConfig;
|
|
48
40
|
}
|
|
41
|
+
export interface WebConfig {
|
|
42
|
+
name?: string;
|
|
43
|
+
commands: {
|
|
44
|
+
dev: string;
|
|
45
|
+
build?: string;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export interface Web {
|
|
49
|
+
root: string;
|
|
50
|
+
config: WebConfig;
|
|
51
|
+
framework?: string;
|
|
52
|
+
}
|
|
49
53
|
export interface App {
|
|
50
54
|
root: string;
|
|
55
|
+
webs: Web[];
|
|
51
56
|
config: AppConfig;
|
|
52
57
|
extensions: Extension[];
|
|
53
58
|
}
|
package/dist/util/app-loader.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Path, Filesystem } from '@youcan/cli-kit';
|
|
2
|
-
import { APP_CONFIG_FILENAME, DEFAULT_EXTENSIONS_DIR, EXTENSION_CONFIG_FILENAME } from '../constants.js';
|
|
2
|
+
import { APP_CONFIG_FILENAME, DEFAULT_EXTENSIONS_DIR, EXTENSION_CONFIG_FILENAME, DEFAULT_WEBS_DIR, WEB_CONFIG_FILENAME } from '../constants.js';
|
|
3
3
|
|
|
4
4
|
async function load() {
|
|
5
5
|
const path = Path.resolve(Path.cwd(), APP_CONFIG_FILENAME);
|
|
@@ -9,9 +9,15 @@ async function load() {
|
|
|
9
9
|
const config = await Filesystem.readJsonFile(path);
|
|
10
10
|
const app = {
|
|
11
11
|
config,
|
|
12
|
+
webs: [],
|
|
12
13
|
extensions: [],
|
|
13
14
|
root: Path.cwd(),
|
|
14
15
|
};
|
|
16
|
+
app.extensions = await loadExtensions(app);
|
|
17
|
+
app.webs = await loadWebs(app);
|
|
18
|
+
return app;
|
|
19
|
+
}
|
|
20
|
+
async function loadExtensions(app) {
|
|
15
21
|
const pattern = Path.join(app.root, `${DEFAULT_EXTENSIONS_DIR}/*`, EXTENSION_CONFIG_FILENAME);
|
|
16
22
|
const paths = await Filesystem.glob(pattern);
|
|
17
23
|
const promises = paths.map(async (p) => {
|
|
@@ -20,8 +26,16 @@ async function load() {
|
|
|
20
26
|
config: await Filesystem.readJsonFile(p),
|
|
21
27
|
};
|
|
22
28
|
});
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
return await Promise.all(promises);
|
|
30
|
+
}
|
|
31
|
+
async function loadWebs(app) {
|
|
32
|
+
const pattern = Path.join(app.root, DEFAULT_WEBS_DIR, WEB_CONFIG_FILENAME);
|
|
33
|
+
const paths = await Filesystem.glob(pattern);
|
|
34
|
+
const promises = paths.map(async (p) => ({
|
|
35
|
+
root: Path.dirname(p),
|
|
36
|
+
config: await Filesystem.readJsonFile(p),
|
|
37
|
+
}));
|
|
38
|
+
return await Promise.all(promises);
|
|
25
39
|
}
|
|
26
40
|
|
|
27
41
|
export { load };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@youcan/app",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.1.0-beta.
|
|
4
|
+
"version": "1.1.0-beta.12",
|
|
5
5
|
"description": "OCLIF plugin for building apps",
|
|
6
6
|
"author": "YouCan <contact@youcan.shop> (https://youcan.shop)",
|
|
7
7
|
"license": "MIT",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@oclif/core": "^2.15.0",
|
|
19
|
-
"@youcan/cli-kit": "1.1.0-beta.
|
|
19
|
+
"@youcan/cli-kit": "1.1.0-beta.12"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@oclif/plugin-legacy": "^1.3.0",
|