juo 0.0.1-alpha.0 → 0.0.1-alpha.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 +82 -0
- package/bin/dev.cmd +3 -0
- package/bin/dev.js +5 -0
- package/bin/run.cmd +3 -0
- package/bin/run.js +4 -1
- package/dist/base-command.d.ts +23 -0
- package/dist/base-command.js +122 -0
- package/dist/commands/publish/index.d.ts +14 -0
- package/dist/commands/publish/index.js +119 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/standalone.d.ts +1 -0
- package/dist/standalone.js +2 -0
- package/oclif.manifest.json +48 -0
- package/package.json +64 -7
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
@juo/orion-cli
|
|
2
|
+
=================
|
|
3
|
+
|
|
4
|
+
CLI for publishing Orion blocks to registry
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
[](https://oclif.io)
|
|
8
|
+
[](https://npmjs.org/package/@juo/orion-cli)
|
|
9
|
+
[](https://npmjs.org/package/@juo/orion-cli)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
<!-- toc -->
|
|
13
|
+
* [Usage](#usage)
|
|
14
|
+
* [Commands](#commands)
|
|
15
|
+
<!-- tocstop -->
|
|
16
|
+
# Usage
|
|
17
|
+
<!-- usage -->
|
|
18
|
+
```sh-session
|
|
19
|
+
$ npm install -g juo
|
|
20
|
+
$ juo COMMAND
|
|
21
|
+
running command...
|
|
22
|
+
$ juo (--version)
|
|
23
|
+
juo/0.0.1-alpha.1 darwin-arm64 node-v22.13.1
|
|
24
|
+
$ juo --help [COMMAND]
|
|
25
|
+
USAGE
|
|
26
|
+
$ juo COMMAND
|
|
27
|
+
...
|
|
28
|
+
```
|
|
29
|
+
<!-- usagestop -->
|
|
30
|
+
# Commands
|
|
31
|
+
<!-- commands -->
|
|
32
|
+
* [`juo help [COMMAND]`](#juo-help-command)
|
|
33
|
+
* [`juo publish`](#juo-publish)
|
|
34
|
+
|
|
35
|
+
## `juo help [COMMAND]`
|
|
36
|
+
|
|
37
|
+
Display help for juo.
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
USAGE
|
|
41
|
+
$ juo help [COMMAND...] [-n]
|
|
42
|
+
|
|
43
|
+
ARGUMENTS
|
|
44
|
+
COMMAND... Command to show help for.
|
|
45
|
+
|
|
46
|
+
FLAGS
|
|
47
|
+
-n, --nested-commands Include all nested commands in the output.
|
|
48
|
+
|
|
49
|
+
DESCRIPTION
|
|
50
|
+
Display help for juo.
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v6.2.33/src/commands/help.ts)_
|
|
54
|
+
|
|
55
|
+
## `juo publish`
|
|
56
|
+
|
|
57
|
+
Publish theme files from the ./dist directory to the remote registry.
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
USAGE
|
|
61
|
+
$ juo publish [--reconfigure] [-t <value>]
|
|
62
|
+
|
|
63
|
+
FLAGS
|
|
64
|
+
-t, --theme=<value> [default: default] Specify the name of the theme to publish
|
|
65
|
+
|
|
66
|
+
GLOBAL FLAGS
|
|
67
|
+
--reconfigure Reconfigure settings
|
|
68
|
+
|
|
69
|
+
DESCRIPTION
|
|
70
|
+
Publish theme files from the ./dist directory to the remote registry.
|
|
71
|
+
|
|
72
|
+
EXAMPLES
|
|
73
|
+
$ juo publish
|
|
74
|
+
Publish the default theme files.
|
|
75
|
+
|
|
76
|
+
$ juo publish --theme custom-theme
|
|
77
|
+
Publish a custom theme files.
|
|
78
|
+
|
|
79
|
+
$ juo publish --reconfigure
|
|
80
|
+
Reconfigure settings and publish.
|
|
81
|
+
```
|
|
82
|
+
<!-- commandsstop -->
|
package/bin/dev.cmd
ADDED
package/bin/dev.js
ADDED
package/bin/run.cmd
ADDED
package/bin/run.js
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Command, Flags, Interfaces } from '@oclif/core';
|
|
2
|
+
export interface OrionConfig {
|
|
3
|
+
JUO_API_KEY: string;
|
|
4
|
+
JUO_API_URL: string;
|
|
5
|
+
}
|
|
6
|
+
type Flags<T extends typeof Command> = Interfaces.InferredFlags<(typeof BaseCommand)['baseFlags'] & T['flags']>;
|
|
7
|
+
type Args<T extends typeof Command> = Interfaces.InferredArgs<T['args']>;
|
|
8
|
+
export declare abstract class BaseCommand<T extends typeof Command> extends Command {
|
|
9
|
+
static baseFlags: {
|
|
10
|
+
reconfigure: Interfaces.BooleanFlag<boolean>;
|
|
11
|
+
};
|
|
12
|
+
protected args: Args<T>;
|
|
13
|
+
protected flags: Flags<T>;
|
|
14
|
+
protected get configFileName(): string;
|
|
15
|
+
protected get configFilePath(): string;
|
|
16
|
+
protected configExists(): boolean;
|
|
17
|
+
protected ensureConfig(reconfigure?: boolean): Promise<OrionConfig>;
|
|
18
|
+
init(): Promise<void>;
|
|
19
|
+
protected loadConfig(): Partial<OrionConfig>;
|
|
20
|
+
protected saveConfig(config: Partial<OrionConfig>): void;
|
|
21
|
+
protected validateConfig(config: Partial<OrionConfig>): config is OrionConfig;
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
export class BaseCommand extends Command {
|
|
6
|
+
static baseFlags = {
|
|
7
|
+
reconfigure: Flags.boolean({
|
|
8
|
+
default: false,
|
|
9
|
+
description: 'Reconfigure settings',
|
|
10
|
+
helpGroup: 'GLOBAL',
|
|
11
|
+
}),
|
|
12
|
+
};
|
|
13
|
+
args;
|
|
14
|
+
flags;
|
|
15
|
+
get configFileName() {
|
|
16
|
+
return 'config.json';
|
|
17
|
+
}
|
|
18
|
+
get configFilePath() {
|
|
19
|
+
return path.join(this.config.configDir, this.configFileName);
|
|
20
|
+
}
|
|
21
|
+
configExists() {
|
|
22
|
+
return fs.existsSync(this.configFilePath);
|
|
23
|
+
}
|
|
24
|
+
async ensureConfig(reconfigure = false) {
|
|
25
|
+
let config = {};
|
|
26
|
+
if (this.configExists()) {
|
|
27
|
+
try {
|
|
28
|
+
config = this.loadConfig();
|
|
29
|
+
if (this.validateConfig(config) && !reconfigure) {
|
|
30
|
+
this.log(`Found configuration at ${this.configFilePath}`);
|
|
31
|
+
return config;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
this.log(`Warning: Could not parse existing config at ${this.configFilePath}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (reconfigure && this.validateConfig(config)) {
|
|
39
|
+
this.log('Reconfiguring settings...');
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
this.log('Configuration incomplete. Setting up...');
|
|
43
|
+
}
|
|
44
|
+
const questions = [];
|
|
45
|
+
if (!config.JUO_API_URL || reconfigure) {
|
|
46
|
+
questions.push({
|
|
47
|
+
default: config.JUO_API_URL,
|
|
48
|
+
message: 'Enter the Juo API URL:',
|
|
49
|
+
name: 'JUO_API_URL',
|
|
50
|
+
type: 'input',
|
|
51
|
+
validate(input) {
|
|
52
|
+
if (!input.trim()) {
|
|
53
|
+
return 'Juo API URL is required';
|
|
54
|
+
}
|
|
55
|
+
return true;
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
if (!config.JUO_API_KEY || reconfigure) {
|
|
60
|
+
questions.push({
|
|
61
|
+
message: 'Enter your Juo API key:',
|
|
62
|
+
name: 'JUO_API_KEY',
|
|
63
|
+
type: 'password',
|
|
64
|
+
validate(input) {
|
|
65
|
+
if (!input.trim()) {
|
|
66
|
+
return 'Juo API key is required';
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (questions.length === 0) {
|
|
73
|
+
return config;
|
|
74
|
+
}
|
|
75
|
+
const response = await inquirer.prompt(questions);
|
|
76
|
+
if (response.JUO_API_URL) {
|
|
77
|
+
config.JUO_API_URL = response.JUO_API_URL.trim();
|
|
78
|
+
}
|
|
79
|
+
if (response.JUO_API_KEY) {
|
|
80
|
+
config.JUO_API_KEY = response.JUO_API_KEY.trim();
|
|
81
|
+
}
|
|
82
|
+
this.saveConfig(config);
|
|
83
|
+
this.log(`Saved configuration to ${this.configFilePath}`);
|
|
84
|
+
if (this.validateConfig(config)) {
|
|
85
|
+
return config;
|
|
86
|
+
}
|
|
87
|
+
throw new Error('Failed to create valid configuration');
|
|
88
|
+
}
|
|
89
|
+
async init() {
|
|
90
|
+
await super.init();
|
|
91
|
+
const { args, flags } = await this.parse({
|
|
92
|
+
args: this.ctor.args,
|
|
93
|
+
baseFlags: super.ctor.baseFlags,
|
|
94
|
+
flags: this.ctor.flags,
|
|
95
|
+
strict: this.ctor.strict,
|
|
96
|
+
});
|
|
97
|
+
this.flags = flags;
|
|
98
|
+
this.args = args;
|
|
99
|
+
}
|
|
100
|
+
loadConfig() {
|
|
101
|
+
if (!this.configExists()) {
|
|
102
|
+
throw new Error(`Configuration file not found at ${this.configFilePath}`);
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
const configContent = fs.readFileSync(this.configFilePath, 'utf8');
|
|
106
|
+
return JSON.parse(configContent);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
throw new Error(`Failed to parse configuration file at ${this.configFilePath}: ${error}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
saveConfig(config) {
|
|
113
|
+
fs.mkdirSync(this.config.configDir, { recursive: true });
|
|
114
|
+
fs.writeFileSync(this.configFilePath, JSON.stringify(config, null, 2), { encoding: 'utf8' });
|
|
115
|
+
}
|
|
116
|
+
validateConfig(config) {
|
|
117
|
+
return Boolean(config.JUO_API_KEY &&
|
|
118
|
+
config.JUO_API_KEY.length > 0 &&
|
|
119
|
+
config.JUO_API_URL &&
|
|
120
|
+
config.JUO_API_URL.length > 0);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command.js';
|
|
2
|
+
export default class Publish extends BaseCommand<typeof Publish> {
|
|
3
|
+
static args: {};
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {
|
|
7
|
+
theme: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
};
|
|
9
|
+
getAllFiles(dirPath: string, basePath: string): string[];
|
|
10
|
+
run(): Promise<void>;
|
|
11
|
+
private getAwsConnectionInfo;
|
|
12
|
+
private uploadFile;
|
|
13
|
+
private uploadFiles;
|
|
14
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
|
2
|
+
import { Flags } from '@oclif/core';
|
|
3
|
+
import mime from 'mime';
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import asyncPool from 'tiny-async-pool';
|
|
7
|
+
import { BaseCommand } from '../../base-command.js';
|
|
8
|
+
export default class Publish extends BaseCommand {
|
|
9
|
+
static args = {};
|
|
10
|
+
static description = ' Publish theme files from the ./dist directory to the remote registry.';
|
|
11
|
+
static examples = [
|
|
12
|
+
`<%= config.bin %> publish
|
|
13
|
+
Publish the default theme files.
|
|
14
|
+
`,
|
|
15
|
+
`<%= config.bin %> publish --theme custom-theme
|
|
16
|
+
Publish a custom theme files.
|
|
17
|
+
`,
|
|
18
|
+
`<%= config.bin %> publish --reconfigure
|
|
19
|
+
Reconfigure settings and publish.
|
|
20
|
+
`,
|
|
21
|
+
];
|
|
22
|
+
static flags = {
|
|
23
|
+
theme: Flags.string({
|
|
24
|
+
char: 't',
|
|
25
|
+
default: 'default',
|
|
26
|
+
description: 'Specify the name of the theme to publish',
|
|
27
|
+
}),
|
|
28
|
+
};
|
|
29
|
+
getAllFiles(dirPath, basePath) {
|
|
30
|
+
const files = [];
|
|
31
|
+
const items = fs.readdirSync(dirPath);
|
|
32
|
+
for (const item of items) {
|
|
33
|
+
const fullPath = path.join(dirPath, item);
|
|
34
|
+
const stat = fs.statSync(fullPath);
|
|
35
|
+
if (stat.isFile()) {
|
|
36
|
+
const relativePath = path.relative(basePath, fullPath);
|
|
37
|
+
files.push(relativePath);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return files;
|
|
41
|
+
}
|
|
42
|
+
async run() {
|
|
43
|
+
this.log(`🚀 Publishing ${this.flags.theme} theme files to registry...`);
|
|
44
|
+
try {
|
|
45
|
+
const config = await this.ensureConfig(this.flags.reconfigure);
|
|
46
|
+
this.log('📤 Uploading files...');
|
|
47
|
+
await this.uploadFiles(this.flags.theme, config);
|
|
48
|
+
this.log('✅ Publishing completed successfully!');
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
this.error(`❌ Publishing failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async getAwsConnectionInfo(config, themeName) {
|
|
55
|
+
try {
|
|
56
|
+
// eslint-disable-next-line n/no-unsupported-features/node-builtins
|
|
57
|
+
const response = await fetch(`${config.JUO_API_URL}/get-publish-token`, {
|
|
58
|
+
body: JSON.stringify({ theme: themeName }),
|
|
59
|
+
headers: {
|
|
60
|
+
Accept: 'application/json',
|
|
61
|
+
'Content-Type': 'application/json',
|
|
62
|
+
'X-Juo-Admin-Api-Key': config.JUO_API_KEY,
|
|
63
|
+
},
|
|
64
|
+
method: 'POST',
|
|
65
|
+
});
|
|
66
|
+
if (response.status !== 200) {
|
|
67
|
+
this.error(`API request failed with status ${response.status}`);
|
|
68
|
+
}
|
|
69
|
+
if (response.headers.get('Content-Type')?.includes('application/json')) {
|
|
70
|
+
return (await response.json());
|
|
71
|
+
}
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
this.error(`Failed to fetch credentials: ${error instanceof Error ? error.message : String(error)}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async uploadFile(client, distDir, file, options) {
|
|
79
|
+
if (file.split('/').some((item) => item.startsWith('.'))) {
|
|
80
|
+
return file;
|
|
81
|
+
}
|
|
82
|
+
const filepath = path.join(distDir, file);
|
|
83
|
+
const stream = fs.createReadStream(filepath);
|
|
84
|
+
const command = new PutObjectCommand({
|
|
85
|
+
Body: stream,
|
|
86
|
+
Bucket: options.bucket,
|
|
87
|
+
CacheControl: 'max-age=3600, must-revalidate',
|
|
88
|
+
ContentType: mime.getType(file) || 'application/octet-stream',
|
|
89
|
+
Key: `${options.prefix}${file}`,
|
|
90
|
+
});
|
|
91
|
+
this.log(`📤 Uploading file '${file}'...`);
|
|
92
|
+
await client.send(command);
|
|
93
|
+
return file;
|
|
94
|
+
}
|
|
95
|
+
async uploadFiles(themeName, config) {
|
|
96
|
+
const connectionInfo = await this.getAwsConnectionInfo(config, themeName);
|
|
97
|
+
if (!connectionInfo) {
|
|
98
|
+
throw new Error('Failed to get AWS connection info');
|
|
99
|
+
}
|
|
100
|
+
const { bucket, credentials, prefix, region } = connectionInfo;
|
|
101
|
+
const client = new S3Client({
|
|
102
|
+
credentials,
|
|
103
|
+
region,
|
|
104
|
+
});
|
|
105
|
+
const distDir = path.resolve(process.cwd(), 'dist');
|
|
106
|
+
if (!fs.existsSync(distDir)) {
|
|
107
|
+
this.error('dist directory not found');
|
|
108
|
+
}
|
|
109
|
+
const files = this.getAllFiles(distDir, distDir);
|
|
110
|
+
if (files.length === 0) {
|
|
111
|
+
this.log('No files found in dist directory');
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
this.log(`Found ${files.length} file(s) to upload`);
|
|
115
|
+
for await (const file of asyncPool(4, files, (file) => this.uploadFile(client, distDir, file, { bucket, prefix }))) {
|
|
116
|
+
this.log(`✅ Uploaded file '${file}'`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { run } from '@oclif/core';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { run } from '@oclif/core';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"commands": {
|
|
3
|
+
"publish": {
|
|
4
|
+
"aliases": [],
|
|
5
|
+
"args": {},
|
|
6
|
+
"description": " Publish theme files from the ./dist directory to the remote registry.",
|
|
7
|
+
"examples": [
|
|
8
|
+
"<%= config.bin %> publish\nPublish the default theme files.\n",
|
|
9
|
+
"<%= config.bin %> publish --theme custom-theme\nPublish a custom theme files.\n",
|
|
10
|
+
"<%= config.bin %> publish --reconfigure\nReconfigure settings and publish.\n"
|
|
11
|
+
],
|
|
12
|
+
"flags": {
|
|
13
|
+
"reconfigure": {
|
|
14
|
+
"description": "Reconfigure settings",
|
|
15
|
+
"helpGroup": "GLOBAL",
|
|
16
|
+
"name": "reconfigure",
|
|
17
|
+
"allowNo": false,
|
|
18
|
+
"type": "boolean"
|
|
19
|
+
},
|
|
20
|
+
"theme": {
|
|
21
|
+
"char": "t",
|
|
22
|
+
"description": "Specify the name of the theme to publish",
|
|
23
|
+
"name": "theme",
|
|
24
|
+
"default": "default",
|
|
25
|
+
"hasDynamicHelp": false,
|
|
26
|
+
"multiple": false,
|
|
27
|
+
"type": "option"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"hasDynamicHelp": false,
|
|
31
|
+
"hiddenAliases": [],
|
|
32
|
+
"id": "publish",
|
|
33
|
+
"pluginAlias": "juo",
|
|
34
|
+
"pluginName": "juo",
|
|
35
|
+
"pluginType": "core",
|
|
36
|
+
"strict": true,
|
|
37
|
+
"enableJsonFlag": false,
|
|
38
|
+
"isESM": true,
|
|
39
|
+
"relativePath": [
|
|
40
|
+
"dist",
|
|
41
|
+
"commands",
|
|
42
|
+
"publish",
|
|
43
|
+
"index.js"
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"version": "0.0.1-alpha.1"
|
|
48
|
+
}
|
package/package.json
CHANGED
|
@@ -1,16 +1,73 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "juo",
|
|
3
|
-
"
|
|
4
|
-
"version": "0.0.1-alpha.
|
|
5
|
-
"
|
|
6
|
-
"type": "module",
|
|
3
|
+
"description": "A CLI tool for the Juo platform",
|
|
4
|
+
"version": "0.0.1-alpha.1",
|
|
5
|
+
"author": "Juo (https://juo.io)",
|
|
7
6
|
"bin": {
|
|
8
7
|
"juo": "./bin/run.js"
|
|
9
8
|
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"@aws-sdk/client-s3": "3.901.0",
|
|
11
|
+
"@oclif/core": "4.5.4",
|
|
12
|
+
"@oclif/plugin-help": "6.2.33",
|
|
13
|
+
"inquirer": "9.3.8",
|
|
14
|
+
"mime": "4.1.0",
|
|
15
|
+
"tiny-async-pool": "2.1.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@eslint/compat": "1.4.0",
|
|
19
|
+
"@oclif/prettier-config": "0.2.1",
|
|
20
|
+
"@oclif/test": "4.1.14",
|
|
21
|
+
"@types/chai": "4.3.20",
|
|
22
|
+
"@types/inquirer": "9.0.9",
|
|
23
|
+
"@types/mocha": "10.0.10",
|
|
24
|
+
"@types/node": "18.19.5",
|
|
25
|
+
"@types/tiny-async-pool": "2.0.3",
|
|
26
|
+
"chai": "4.5.0",
|
|
27
|
+
"eslint": "9.37.0",
|
|
28
|
+
"eslint-config-oclif": "6.0.108",
|
|
29
|
+
"eslint-config-prettier": "10.1.8",
|
|
30
|
+
"mocha": "10.8.2",
|
|
31
|
+
"oclif": "4.22.29",
|
|
32
|
+
"shx": "0.3.4",
|
|
33
|
+
"ts-node": "10.9.2",
|
|
34
|
+
"typescript": "5.7.3"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18.0.0"
|
|
38
|
+
},
|
|
10
39
|
"files": [
|
|
11
|
-
"
|
|
40
|
+
"./bin",
|
|
41
|
+
"./dist",
|
|
42
|
+
"./oclif.manifest.json"
|
|
12
43
|
],
|
|
13
|
-
"
|
|
14
|
-
|
|
44
|
+
"homepage": "https://juo.io",
|
|
45
|
+
"keywords": [
|
|
46
|
+
"oclif"
|
|
47
|
+
],
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"main": "dist/index.js",
|
|
50
|
+
"type": "module",
|
|
51
|
+
"oclif": {
|
|
52
|
+
"bin": "juo",
|
|
53
|
+
"dirname": "orion",
|
|
54
|
+
"commands": "./dist/commands",
|
|
55
|
+
"plugins": [
|
|
56
|
+
"@oclif/plugin-help"
|
|
57
|
+
],
|
|
58
|
+
"topicSeparator": " ",
|
|
59
|
+
"topics": {
|
|
60
|
+
"publish": {
|
|
61
|
+
"description": "Publish theme files"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"types": "dist/index.d.ts",
|
|
66
|
+
"scripts": {
|
|
67
|
+
"build": "shx rm -rf dist && tsc -b",
|
|
68
|
+
"lint": "eslint",
|
|
69
|
+
"posttest": "pnpm run lint",
|
|
70
|
+
"test": "mocha --forbid-only \"test/**/*.test.ts\"",
|
|
71
|
+
"version": "oclif readme && git add README.md"
|
|
15
72
|
}
|
|
16
73
|
}
|