@nocobase/cli 2.2.0-alpha.1 → 2.2.0-beta.2
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/bin/node-version.js +35 -0
- package/bin/run.js +6 -0
- package/dist/commands/init.js +4 -8
- package/dist/commands/skills/check.js +4 -5
- package/dist/commands/skills/install.js +5 -0
- package/dist/commands/skills/update.js +17 -4
- package/dist/commands/source/download.js +1 -2
- package/dist/lib/api-command-compat.js +51 -8
- package/dist/lib/skills-manager.js +104 -20
- package/dist/locale/en-US.json +4 -4
- package/dist/locale/zh-CN.json +4 -4
- package/package.json +7 -2
- package/assets/env-proxy/nginx/app.conf.tpl +0 -23
- package/assets/env-proxy/nginx/nocobase.conf.tpl +0 -5
- package/assets/env-proxy/nginx/snippets/dist-location.conf +0 -5
- package/assets/env-proxy/nginx/snippets/gzip.conf +0 -17
- package/assets/env-proxy/nginx/snippets/log-format-http.conf +0 -13
- package/assets/env-proxy/nginx/snippets/maps-http.conf +0 -14
- package/assets/env-proxy/nginx/snippets/mime-types.conf +0 -98
- package/assets/env-proxy/nginx/snippets/proxy-location.conf +0 -17
- package/assets/env-proxy/nginx/snippets/spa-location.conf +0 -6
- package/assets/env-proxy/nginx/snippets/uploads-location.conf +0 -21
- package/scripts/build.mjs +0 -34
- package/scripts/clean.mjs +0 -9
- package/tsconfig.json +0 -19
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const MINIMUM_NODE_MAJOR_VERSION = 22;
|
|
2
|
+
|
|
3
|
+
export function getNodeMajorVersion(version = process.versions.node) {
|
|
4
|
+
const match = String(version ?? '')
|
|
5
|
+
.trim()
|
|
6
|
+
.match(/^v?(\d+)/);
|
|
7
|
+
|
|
8
|
+
if (!match) {
|
|
9
|
+
return Number.NaN;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return Number.parseInt(match[1], 10);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function isSupportedNodeVersion(
|
|
16
|
+
version = process.versions.node,
|
|
17
|
+
minimumMajorVersion = MINIMUM_NODE_MAJOR_VERSION,
|
|
18
|
+
) {
|
|
19
|
+
const majorVersion = getNodeMajorVersion(version);
|
|
20
|
+
return Number.isInteger(majorVersion) && majorVersion >= minimumMajorVersion;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function formatUnsupportedNodeVersionMessage(
|
|
24
|
+
version = process.version,
|
|
25
|
+
minimumMajorVersion = MINIMUM_NODE_MAJOR_VERSION,
|
|
26
|
+
) {
|
|
27
|
+
const currentVersion = String(version ?? '').trim() || 'unknown';
|
|
28
|
+
|
|
29
|
+
return [
|
|
30
|
+
`[nocobase cli]: Node.js ${minimumMajorVersion} or later is required to run nb.`,
|
|
31
|
+
`[nocobase cli]: Current version: ${currentVersion}. Please install Node.js ${minimumMajorVersion} or later and try again.`,
|
|
32
|
+
].join('\n');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { MINIMUM_NODE_MAJOR_VERSION };
|
package/bin/run.js
CHANGED
|
@@ -6,6 +6,7 @@ import { createRequire } from 'node:module';
|
|
|
6
6
|
import path from 'node:path';
|
|
7
7
|
import pc from 'picocolors';
|
|
8
8
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
9
|
+
import { formatUnsupportedNodeVersionMessage, isSupportedNodeVersion } from './node-version.js';
|
|
9
10
|
import { normalizeNodeOptions, normalizeSessionEnv } from './session-env.js';
|
|
10
11
|
|
|
11
12
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -18,6 +19,11 @@ if (process.env.NB_CLI_USE_DIST === '1') {
|
|
|
18
19
|
isDev = false;
|
|
19
20
|
}
|
|
20
21
|
|
|
22
|
+
if (!isSupportedNodeVersion()) {
|
|
23
|
+
console.error(pc.red(formatUnsupportedNodeVersionMessage(process.version)));
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
21
27
|
normalizeSessionEnv();
|
|
22
28
|
normalizeNodeOptions();
|
|
23
29
|
|
package/dist/commands/init.js
CHANGED
|
@@ -246,16 +246,12 @@ function formatBrowserOpenError(error) {
|
|
|
246
246
|
return String(error);
|
|
247
247
|
}
|
|
248
248
|
export default class Init extends Command {
|
|
249
|
-
static summary = 'Set up
|
|
250
|
-
static description = `Set up NocoBase
|
|
249
|
+
static summary = 'Set up or connect a NocoBase environment in the current workspace';
|
|
250
|
+
static description = `Set up NocoBase in the current workspace.
|
|
251
251
|
|
|
252
|
-
\`nb init\`
|
|
252
|
+
\`nb init\` helps you install a new NocoBase app, take over managing one that already exists on this machine, or connect a remote NocoBase app and save it as a CLI env.
|
|
253
253
|
|
|
254
|
-
|
|
255
|
-
- Take over managing an app that already exists on this machine by reusing its database.
|
|
256
|
-
- Connect a remote NocoBase app and save it as a CLI env.
|
|
257
|
-
|
|
258
|
-
It can also install NocoBase AI coding skills (\`nocobase/skills\`) so agents get the project-specific workflow guidance.
|
|
254
|
+
You can use the saved environment directly, or let a coding agent access it later. It can also install NocoBase AI coding skills (\`nocobase/skills\`) when you want agent-specific workflow guidance.
|
|
259
255
|
|
|
260
256
|
If setup was interrupted earlier, use \`--resume\` with an existing env name to continue from the saved workspace config.
|
|
261
257
|
|
|
@@ -12,10 +12,7 @@ import { printInfo, renderTable } from '../../lib/ui.js';
|
|
|
12
12
|
export default class SkillsCheck extends Command {
|
|
13
13
|
static summary = 'Check the globally installed NocoBase AI coding skills';
|
|
14
14
|
static description = 'Inspect the global NocoBase AI coding skills and report whether they are managed by the CLI and whether an update is available.';
|
|
15
|
-
static examples = [
|
|
16
|
-
'<%= config.bin %> <%= command.id %>',
|
|
17
|
-
'<%= config.bin %> <%= command.id %> --json',
|
|
18
|
-
];
|
|
15
|
+
static examples = ['<%= config.bin %> <%= command.id %>', '<%= config.bin %> <%= command.id %> --json'];
|
|
19
16
|
static flags = {
|
|
20
17
|
json: Flags.boolean({
|
|
21
18
|
description: 'Output the result as JSON',
|
|
@@ -25,6 +22,7 @@ export default class SkillsCheck extends Command {
|
|
|
25
22
|
async run() {
|
|
26
23
|
const { flags } = await this.parse(SkillsCheck);
|
|
27
24
|
const status = await inspectSkillsStatus();
|
|
25
|
+
const displaySkillNames = status.packageSkillNames.length ? status.packageSkillNames : status.installedSkillNames;
|
|
28
26
|
if (flags.json) {
|
|
29
27
|
this.log(JSON.stringify({
|
|
30
28
|
ok: true,
|
|
@@ -35,6 +33,7 @@ export default class SkillsCheck extends Command {
|
|
|
35
33
|
managedByNb: status.managedByNb,
|
|
36
34
|
sourcePackage: status.sourcePackage,
|
|
37
35
|
npmPackageName: status.npmPackageName,
|
|
36
|
+
packageSkillNames: status.packageSkillNames,
|
|
38
37
|
installedSkillNames: status.installedSkillNames,
|
|
39
38
|
installedVersion: status.installedVersion,
|
|
40
39
|
latestVersion: status.latestVersion,
|
|
@@ -50,7 +49,7 @@ export default class SkillsCheck extends Command {
|
|
|
50
49
|
['Skills home', status.globalRoot],
|
|
51
50
|
['Installed', status.installed ? 'yes' : 'no'],
|
|
52
51
|
['Managed by nb', status.managedByNb ? 'yes' : 'no'],
|
|
53
|
-
['Installed skills',
|
|
52
|
+
['Installed skills', displaySkillNames.length ? displaySkillNames.join(', ') : '(none)'],
|
|
54
53
|
['Installed version', status.installedVersion ?? '(unknown)'],
|
|
55
54
|
['Latest version', status.latestVersion ?? '(unknown)'],
|
|
56
55
|
['Update available', status.updateAvailable === null ? 'unknown' : status.updateAvailable ? 'yes' : 'no'],
|
|
@@ -16,6 +16,7 @@ export default class SkillsInstall extends Command {
|
|
|
16
16
|
static examples = [
|
|
17
17
|
'<%= config.bin %> <%= command.id %>',
|
|
18
18
|
'<%= config.bin %> <%= command.id %> --yes',
|
|
19
|
+
'<%= config.bin %> <%= command.id %> --version 1.0.4',
|
|
19
20
|
'<%= config.bin %> <%= command.id %> --json',
|
|
20
21
|
];
|
|
21
22
|
static flags = {
|
|
@@ -32,6 +33,9 @@ export default class SkillsInstall extends Command {
|
|
|
32
33
|
description: 'Show detailed install output',
|
|
33
34
|
default: false,
|
|
34
35
|
}),
|
|
36
|
+
version: Flags.string({
|
|
37
|
+
description: 'Install a specific @nocobase/skills version',
|
|
38
|
+
}),
|
|
35
39
|
};
|
|
36
40
|
async run() {
|
|
37
41
|
const { flags } = await this.parse(SkillsInstall);
|
|
@@ -52,6 +56,7 @@ export default class SkillsInstall extends Command {
|
|
|
52
56
|
}
|
|
53
57
|
}
|
|
54
58
|
const result = await installNocoBaseSkills({
|
|
59
|
+
targetVersion: flags.version,
|
|
55
60
|
verbose: flags.verbose,
|
|
56
61
|
});
|
|
57
62
|
if (flags.json) {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { Command, Flags } from '@oclif/core';
|
|
10
10
|
import { confirm } from "../../lib/inquirer.js";
|
|
11
|
-
import { setVerboseMode } from '../../lib/ui.js';
|
|
11
|
+
import { setVerboseMode, startTask, stopTask } from '../../lib/ui.js';
|
|
12
12
|
import { updateNocoBaseSkills } from '../../lib/skills-manager.js';
|
|
13
13
|
export default class SkillsUpdate extends Command {
|
|
14
14
|
static summary = 'Update the globally installed NocoBase AI coding skills';
|
|
@@ -16,6 +16,7 @@ export default class SkillsUpdate extends Command {
|
|
|
16
16
|
static examples = [
|
|
17
17
|
'<%= config.bin %> <%= command.id %>',
|
|
18
18
|
'<%= config.bin %> <%= command.id %> --yes',
|
|
19
|
+
'<%= config.bin %> <%= command.id %> --version 1.0.4',
|
|
19
20
|
'<%= config.bin %> <%= command.id %> --json',
|
|
20
21
|
];
|
|
21
22
|
static flags = {
|
|
@@ -32,6 +33,9 @@ export default class SkillsUpdate extends Command {
|
|
|
32
33
|
description: 'Show detailed update output',
|
|
33
34
|
default: false,
|
|
34
35
|
}),
|
|
36
|
+
version: Flags.string({
|
|
37
|
+
description: 'Sync to a specific @nocobase/skills version',
|
|
38
|
+
}),
|
|
35
39
|
};
|
|
36
40
|
async run() {
|
|
37
41
|
const { flags } = await this.parse(SkillsUpdate);
|
|
@@ -51,8 +55,19 @@ export default class SkillsUpdate extends Command {
|
|
|
51
55
|
return;
|
|
52
56
|
}
|
|
53
57
|
}
|
|
58
|
+
const shouldShowLoading = !flags.json && !flags.verbose;
|
|
59
|
+
if (shouldShowLoading) {
|
|
60
|
+
startTask(flags.version
|
|
61
|
+
? `Syncing NocoBase AI coding skills to ${flags.version}...`
|
|
62
|
+
: 'Updating NocoBase AI coding skills...');
|
|
63
|
+
}
|
|
54
64
|
const result = await updateNocoBaseSkills({
|
|
65
|
+
targetVersion: flags.version,
|
|
55
66
|
verbose: flags.verbose,
|
|
67
|
+
}).finally(() => {
|
|
68
|
+
if (shouldShowLoading) {
|
|
69
|
+
stopTask();
|
|
70
|
+
}
|
|
56
71
|
});
|
|
57
72
|
if (flags.json) {
|
|
58
73
|
this.log(JSON.stringify({
|
|
@@ -80,8 +95,6 @@ export default class SkillsUpdate extends Command {
|
|
|
80
95
|
: 'NocoBase AI coding skills are up to date.');
|
|
81
96
|
return;
|
|
82
97
|
}
|
|
83
|
-
this.log(flags.verbose
|
|
84
|
-
? 'Updated the global NocoBase AI coding skills.'
|
|
85
|
-
: 'Updated NocoBase AI coding skills globally.');
|
|
98
|
+
this.log(flags.verbose ? 'Updated the global NocoBase AI coding skills.' : 'Updated NocoBase AI coding skills globally.');
|
|
86
99
|
}
|
|
87
100
|
}
|
|
@@ -16,7 +16,7 @@ import { DEFAULT_DOCKER_REGISTRY, DEFAULT_DOCKER_REGISTRY_ZH_CN, resolveDockerIm
|
|
|
16
16
|
import { run } from "../../lib/run-npm.js";
|
|
17
17
|
import { printVerbose, setVerboseMode, startTask, stopTask, updateTask } from '../../lib/ui.js';
|
|
18
18
|
const DEFAULT_DOCKER_PLATFORM = 'auto';
|
|
19
|
-
const DEFAULT_DOWNLOAD_VERSION = '
|
|
19
|
+
const DEFAULT_DOWNLOAD_VERSION = 'latest';
|
|
20
20
|
const downloadText = (key, values) => localeText(`commands.download.${key}`, values);
|
|
21
21
|
const downloadTranslatedText = (key, values, fallback) => translateCli(`commands.download.${key}`, values, { fallback });
|
|
22
22
|
function defaultOutputDirForVersion(versionTag) {
|
|
@@ -276,7 +276,6 @@ export default class SourceDownload extends Command {
|
|
|
276
276
|
value: 'latest',
|
|
277
277
|
label: downloadText('prompts.version.latestLabel'),
|
|
278
278
|
hint: downloadText('prompts.version.latestHint'),
|
|
279
|
-
disabled: true,
|
|
280
279
|
},
|
|
281
280
|
{
|
|
282
281
|
value: 'beta',
|
|
@@ -114,12 +114,22 @@ function compareWithOperator(version, operator, expected) {
|
|
|
114
114
|
}
|
|
115
115
|
function normalizeAppByChannelComparableVersion(version) {
|
|
116
116
|
const normalized = String(version ?? '').trim();
|
|
117
|
-
const match = normalized.match(/^(\d+\.\d+\.\d+)
|
|
117
|
+
const match = normalized.match(/^(\d+\.\d+\.\d+)(?:-([0-9A-Za-z-.]+))?$/);
|
|
118
118
|
if (!match) {
|
|
119
119
|
return normalized;
|
|
120
120
|
}
|
|
121
|
-
const [, base,
|
|
122
|
-
|
|
121
|
+
const [, base, prerelease] = match;
|
|
122
|
+
if (!prerelease) {
|
|
123
|
+
return base;
|
|
124
|
+
}
|
|
125
|
+
const [channel, sequence] = prerelease.split('.');
|
|
126
|
+
if ((channel === 'alpha' || channel === 'beta') && sequence && /^\d+$/.test(sequence)) {
|
|
127
|
+
return `${base}-${channel}.${sequence}`;
|
|
128
|
+
}
|
|
129
|
+
if (channel === 'alpha' || channel === 'beta') {
|
|
130
|
+
return `${base}-${channel}`;
|
|
131
|
+
}
|
|
132
|
+
return base;
|
|
123
133
|
}
|
|
124
134
|
function normalizeAppByChannelCondition(condition) {
|
|
125
135
|
if (!condition) {
|
|
@@ -134,6 +144,42 @@ function normalizeAppByChannelCondition(condition) {
|
|
|
134
144
|
}
|
|
135
145
|
return normalized;
|
|
136
146
|
}
|
|
147
|
+
function compareAppByChannelVersions(version, expected) {
|
|
148
|
+
const comparableVersion = normalizeAppByChannelComparableVersion(version);
|
|
149
|
+
const comparableExpected = normalizeAppByChannelComparableVersion(expected);
|
|
150
|
+
if (comparableVersion === comparableExpected ||
|
|
151
|
+
comparableVersion.startsWith(`${comparableExpected}.`) ||
|
|
152
|
+
comparableVersion.startsWith(`${comparableExpected}-`)) {
|
|
153
|
+
return 0;
|
|
154
|
+
}
|
|
155
|
+
return compareVersions(comparableVersion, comparableExpected);
|
|
156
|
+
}
|
|
157
|
+
function compareAppByChannelWithOperator(version, operator, expected) {
|
|
158
|
+
const compared = compareAppByChannelVersions(version, expected);
|
|
159
|
+
switch (operator) {
|
|
160
|
+
case 'eq':
|
|
161
|
+
return compared === 0;
|
|
162
|
+
case 'gt':
|
|
163
|
+
return compared > 0;
|
|
164
|
+
case 'gte':
|
|
165
|
+
return compared >= 0;
|
|
166
|
+
case 'lt':
|
|
167
|
+
return compared < 0;
|
|
168
|
+
case 'lte':
|
|
169
|
+
return compared <= 0;
|
|
170
|
+
default:
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function matchesAppByChannelVersionCondition(version, condition) {
|
|
175
|
+
if (!condition) {
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
return ['eq', 'gt', 'gte', 'lt', 'lte'].every((operator) => {
|
|
179
|
+
const expected = condition[operator];
|
|
180
|
+
return expected ? compareAppByChannelWithOperator(version, operator, expected) : true;
|
|
181
|
+
});
|
|
182
|
+
}
|
|
137
183
|
function matchesVersionCondition(version, condition) {
|
|
138
184
|
if (!condition) {
|
|
139
185
|
return true;
|
|
@@ -168,10 +214,7 @@ function resolveAppChannel(version) {
|
|
|
168
214
|
if (channel === 'beta') {
|
|
169
215
|
return 'beta';
|
|
170
216
|
}
|
|
171
|
-
|
|
172
|
-
return 'rc';
|
|
173
|
-
}
|
|
174
|
-
return 'unknownPrerelease';
|
|
217
|
+
return 'stable';
|
|
175
218
|
}
|
|
176
219
|
function evaluateAppByChannelCondition(version, condition) {
|
|
177
220
|
if (!condition) {
|
|
@@ -208,7 +251,7 @@ function evaluateAppByChannelCondition(version, condition) {
|
|
|
208
251
|
const comparableVersion = normalizeAppByChannelComparableVersion(version);
|
|
209
252
|
const comparableCondition = normalizeAppByChannelCondition(channelCondition);
|
|
210
253
|
return {
|
|
211
|
-
result:
|
|
254
|
+
result: matchesAppByChannelVersionCondition(comparableVersion, comparableCondition) ? 'match' : 'mismatch',
|
|
212
255
|
channel,
|
|
213
256
|
condition: channelCondition,
|
|
214
257
|
};
|
|
@@ -154,10 +154,13 @@ export async function listGlobalSkills(options = {}) {
|
|
|
154
154
|
export async function listProjectSkills(options = {}) {
|
|
155
155
|
return await listGlobalSkills(options);
|
|
156
156
|
}
|
|
157
|
-
function pickInstalledNocoBaseSkillNames(installedSkills, state) {
|
|
157
|
+
function pickInstalledNocoBaseSkillNames(installedSkills, state, sourceSkillNames = []) {
|
|
158
158
|
const installedNames = new Set(installedSkills.map((skill) => String(skill.name ?? '').trim()).filter(Boolean));
|
|
159
|
-
|
|
160
|
-
|
|
159
|
+
const managedNames = new Set([...sourceSkillNames, ...(state?.skillNames ?? [])]);
|
|
160
|
+
if (managedNames.size > 0) {
|
|
161
|
+
return Array.from(managedNames)
|
|
162
|
+
.filter((name) => installedNames.has(name))
|
|
163
|
+
.sort();
|
|
161
164
|
}
|
|
162
165
|
return Array.from(installedNames)
|
|
163
166
|
.filter((name) => name.startsWith(NOCOBASE_SKILLS_NAME_PREFIX))
|
|
@@ -194,6 +197,31 @@ async function readCachedSkillsVersion(cacheRoot) {
|
|
|
194
197
|
return undefined;
|
|
195
198
|
}
|
|
196
199
|
}
|
|
200
|
+
async function readCachedPackageSkillNames(globalRoot) {
|
|
201
|
+
const skillsDir = path.join(getCachedSkillsPackageDir(getSkillsCacheRoot(globalRoot)), 'skills');
|
|
202
|
+
try {
|
|
203
|
+
const entries = await fsp.readdir(skillsDir, { withFileTypes: true });
|
|
204
|
+
const skillNames = await Promise.all(entries
|
|
205
|
+
.filter((entry) => entry.isDirectory())
|
|
206
|
+
.map(async (entry) => {
|
|
207
|
+
const skillName = entry.name.trim();
|
|
208
|
+
if (!skillName) {
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
await fsp.access(path.join(skillsDir, skillName, 'SKILL.md'));
|
|
213
|
+
return skillName;
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
return undefined;
|
|
217
|
+
}
|
|
218
|
+
}));
|
|
219
|
+
return skillNames.filter((name) => Boolean(name)).sort();
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
return [];
|
|
223
|
+
}
|
|
224
|
+
}
|
|
197
225
|
async function resolvePackedSkillsTarball(packRoot) {
|
|
198
226
|
const entries = await fsp.readdir(packRoot, { withFileTypes: true });
|
|
199
227
|
const tarballs = entries
|
|
@@ -279,14 +307,16 @@ async function prepareLocalSkillsPackage(globalRoot, options = {}, targetVersion
|
|
|
279
307
|
export async function inspectSkillsStatus(options = {}) {
|
|
280
308
|
const globalRoot = resolveSkillsRoot(options);
|
|
281
309
|
const stateFile = getManagedSkillsStateFile(globalRoot);
|
|
282
|
-
const [installedSkills, managedState] = await Promise.all([
|
|
310
|
+
const [installedSkills, managedState, cachedSkillNames] = await Promise.all([
|
|
283
311
|
listGlobalSkills({
|
|
284
312
|
globalRoot,
|
|
285
313
|
commandOutputFn: options.commandOutputFn,
|
|
286
314
|
}),
|
|
287
315
|
readManagedSkillsState(globalRoot),
|
|
316
|
+
readCachedPackageSkillNames(globalRoot),
|
|
288
317
|
]);
|
|
289
|
-
const installedSkillNames = pickInstalledNocoBaseSkillNames(installedSkills, managedState);
|
|
318
|
+
const installedSkillNames = pickInstalledNocoBaseSkillNames(installedSkills, managedState, cachedSkillNames);
|
|
319
|
+
const packageSkillNames = cachedSkillNames;
|
|
290
320
|
const managedByNb = managedState?.packageName === NOCOBASE_SKILLS_PACKAGE_NAME;
|
|
291
321
|
let latestVersion;
|
|
292
322
|
let registryError;
|
|
@@ -312,6 +342,7 @@ export async function inspectSkillsStatus(options = {}) {
|
|
|
312
342
|
managedByNb,
|
|
313
343
|
sourcePackage: managedState?.sourcePackage ?? NOCOBASE_SKILLS_SOURCE,
|
|
314
344
|
npmPackageName: managedState?.packageName ?? NOCOBASE_SKILLS_PACKAGE_NAME,
|
|
345
|
+
packageSkillNames,
|
|
315
346
|
installedSkillNames,
|
|
316
347
|
latestVersion,
|
|
317
348
|
installedVersion,
|
|
@@ -321,13 +352,18 @@ export async function inspectSkillsStatus(options = {}) {
|
|
|
321
352
|
registryError,
|
|
322
353
|
};
|
|
323
354
|
}
|
|
324
|
-
async function persistManagedSkillsState(globalRoot, options = {}) {
|
|
325
|
-
const installedSkills = await
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
355
|
+
async function persistManagedSkillsState(globalRoot, options = {}, installedVersion) {
|
|
356
|
+
const [installedSkills, managedState, cachedSkillNames] = await Promise.all([
|
|
357
|
+
listGlobalSkills({
|
|
358
|
+
globalRoot,
|
|
359
|
+
commandOutputFn: options.commandOutputFn,
|
|
360
|
+
}),
|
|
361
|
+
readManagedSkillsState(globalRoot),
|
|
362
|
+
readCachedPackageSkillNames(globalRoot),
|
|
363
|
+
]);
|
|
364
|
+
const installedSkillNames = pickInstalledNocoBaseSkillNames(installedSkills, managedState, cachedSkillNames);
|
|
365
|
+
const packageSkillNames = cachedSkillNames.length ? cachedSkillNames : installedSkillNames;
|
|
366
|
+
const cachedVersion = await readCachedSkillsVersion(getSkillsCacheRoot(globalRoot));
|
|
331
367
|
const published = await readPublishedSkillsVersion({
|
|
332
368
|
globalRoot,
|
|
333
369
|
commandOutputFn: options.commandOutputFn,
|
|
@@ -338,8 +374,8 @@ async function persistManagedSkillsState(globalRoot, options = {}) {
|
|
|
338
374
|
sourcePackage: NOCOBASE_SKILLS_SOURCE,
|
|
339
375
|
installedAt: managedState?.installedAt ?? now,
|
|
340
376
|
updatedAt: now,
|
|
341
|
-
installedVersion: published.version,
|
|
342
|
-
skillNames:
|
|
377
|
+
installedVersion: installedVersion ?? cachedVersion ?? published.version,
|
|
378
|
+
skillNames: packageSkillNames,
|
|
343
379
|
});
|
|
344
380
|
return await inspectSkillsStatus({
|
|
345
381
|
globalRoot,
|
|
@@ -349,7 +385,7 @@ async function persistManagedSkillsState(globalRoot, options = {}) {
|
|
|
349
385
|
async function reinstallManagedSkills(globalRoot, options = {}, targetVersion) {
|
|
350
386
|
const prepared = await prepareLocalSkillsPackage(globalRoot, options, targetVersion);
|
|
351
387
|
try {
|
|
352
|
-
await (options.runFn ?? run)('npx', ['-y', 'skills', 'add', prepared.packageDir, '-g', '-y'], {
|
|
388
|
+
await (options.runFn ?? run)('npx', ['-y', 'skills', 'add', prepared.packageDir, '-g', '-y', '--skill', '*'], {
|
|
353
389
|
cwd: globalRoot,
|
|
354
390
|
stdio: options.verbose ? 'inherit' : 'ignore',
|
|
355
391
|
errorName: 'skills add',
|
|
@@ -360,23 +396,50 @@ async function reinstallManagedSkills(globalRoot, options = {}, targetVersion) {
|
|
|
360
396
|
await prepared.cleanup();
|
|
361
397
|
}
|
|
362
398
|
}
|
|
399
|
+
function pickObsoleteManagedSkillNames(installedSkillNames, packageSkillNames) {
|
|
400
|
+
if (!packageSkillNames.length) {
|
|
401
|
+
return [];
|
|
402
|
+
}
|
|
403
|
+
const packageSkillNameSet = new Set(packageSkillNames);
|
|
404
|
+
return installedSkillNames.filter((skillName) => !packageSkillNameSet.has(skillName)).sort();
|
|
405
|
+
}
|
|
406
|
+
async function removeObsoleteManagedSkills(globalRoot, installedSkillNames, options = {}) {
|
|
407
|
+
const packageSkillNames = await readCachedPackageSkillNames(globalRoot);
|
|
408
|
+
const obsoleteSkillNames = pickObsoleteManagedSkillNames(installedSkillNames, packageSkillNames);
|
|
409
|
+
for (const skillName of obsoleteSkillNames) {
|
|
410
|
+
await (options.runFn ?? run)('npx', ['-y', 'skills', 'remove', skillName, '-g', '-y'], {
|
|
411
|
+
cwd: globalRoot,
|
|
412
|
+
stdio: options.verbose ? 'inherit' : 'ignore',
|
|
413
|
+
errorName: 'skills remove',
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
}
|
|
363
417
|
export async function installNocoBaseSkills(options = {}) {
|
|
364
418
|
const globalRoot = resolveSkillsRoot(options);
|
|
365
419
|
const status = await inspectSkillsStatus({
|
|
366
420
|
globalRoot,
|
|
367
421
|
commandOutputFn: options.commandOutputFn,
|
|
368
422
|
});
|
|
369
|
-
|
|
423
|
+
const cachedSkillNames = await readCachedPackageSkillNames(globalRoot);
|
|
424
|
+
const missingCachedSkillNames = cachedSkillNames.filter((name) => !status.installedSkillNames.includes(name));
|
|
425
|
+
const obsoleteSkillNames = pickObsoleteManagedSkillNames(status.installedSkillNames, cachedSkillNames);
|
|
426
|
+
const targetVersion = String(options.targetVersion ?? '').trim() || undefined;
|
|
427
|
+
const targetVersionMatches = !targetVersion || status.installedVersion === targetVersion;
|
|
428
|
+
if (status.installed && targetVersionMatches && missingCachedSkillNames.length === 0 && obsoleteSkillNames.length === 0) {
|
|
370
429
|
return {
|
|
371
430
|
action: 'noop',
|
|
372
431
|
status,
|
|
373
432
|
};
|
|
374
433
|
}
|
|
375
434
|
await ensureSkillsWorkspaceRoot(globalRoot);
|
|
376
|
-
|
|
435
|
+
if (!status.installed || !targetVersionMatches || missingCachedSkillNames.length > 0) {
|
|
436
|
+
const installVersion = targetVersion ?? status.latestVersion;
|
|
437
|
+
await reinstallManagedSkills(globalRoot, options, installVersion);
|
|
438
|
+
}
|
|
439
|
+
await removeObsoleteManagedSkills(globalRoot, status.installedSkillNames, options);
|
|
377
440
|
return {
|
|
378
441
|
action: 'installed',
|
|
379
|
-
status: await persistManagedSkillsState(globalRoot, options),
|
|
442
|
+
status: await persistManagedSkillsState(globalRoot, options, targetVersion),
|
|
380
443
|
};
|
|
381
444
|
}
|
|
382
445
|
export async function updateNocoBaseSkills(options = {}) {
|
|
@@ -385,6 +448,10 @@ export async function updateNocoBaseSkills(options = {}) {
|
|
|
385
448
|
globalRoot,
|
|
386
449
|
commandOutputFn: options.commandOutputFn,
|
|
387
450
|
});
|
|
451
|
+
const cachedSkillNames = await readCachedPackageSkillNames(globalRoot);
|
|
452
|
+
const missingCachedSkillNames = cachedSkillNames.filter((name) => !status.installedSkillNames.includes(name));
|
|
453
|
+
const obsoleteSkillNames = pickObsoleteManagedSkillNames(status.installedSkillNames, cachedSkillNames);
|
|
454
|
+
const targetVersion = String(options.targetVersion ?? '').trim() || undefined;
|
|
388
455
|
if (!status.installed) {
|
|
389
456
|
return {
|
|
390
457
|
action: 'noop',
|
|
@@ -393,8 +460,11 @@ export async function updateNocoBaseSkills(options = {}) {
|
|
|
393
460
|
};
|
|
394
461
|
}
|
|
395
462
|
if (status.managedByNb &&
|
|
463
|
+
!targetVersion &&
|
|
396
464
|
status.latestVersion &&
|
|
397
465
|
status.installedVersion &&
|
|
466
|
+
missingCachedSkillNames.length === 0 &&
|
|
467
|
+
obsoleteSkillNames.length === 0 &&
|
|
398
468
|
compareVersions(status.latestVersion, status.installedVersion) <= 0) {
|
|
399
469
|
return {
|
|
400
470
|
action: 'noop',
|
|
@@ -402,10 +472,24 @@ export async function updateNocoBaseSkills(options = {}) {
|
|
|
402
472
|
status,
|
|
403
473
|
};
|
|
404
474
|
}
|
|
405
|
-
|
|
475
|
+
if (targetVersion &&
|
|
476
|
+
status.installedVersion === targetVersion &&
|
|
477
|
+
missingCachedSkillNames.length === 0 &&
|
|
478
|
+
obsoleteSkillNames.length === 0) {
|
|
479
|
+
return {
|
|
480
|
+
action: 'noop',
|
|
481
|
+
reason: 'up-to-date',
|
|
482
|
+
status,
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
if (!targetVersion || status.installedVersion !== targetVersion || missingCachedSkillNames.length > 0) {
|
|
486
|
+
const installVersion = targetVersion ?? status.latestVersion;
|
|
487
|
+
await reinstallManagedSkills(globalRoot, options, installVersion);
|
|
488
|
+
}
|
|
489
|
+
await removeObsoleteManagedSkills(globalRoot, status.installedSkillNames, options);
|
|
406
490
|
return {
|
|
407
491
|
action: 'updated',
|
|
408
|
-
status: await persistManagedSkillsState(globalRoot, options),
|
|
492
|
+
status: await persistManagedSkillsState(globalRoot, options, targetVersion),
|
|
409
493
|
};
|
|
410
494
|
}
|
|
411
495
|
export async function removeNocoBaseSkills(options = {}) {
|
package/dist/locale/en-US.json
CHANGED
|
@@ -399,7 +399,7 @@
|
|
|
399
399
|
"envExists": "Env \"{{envName}}\" already exists. Choose another env name."
|
|
400
400
|
},
|
|
401
401
|
"messages": {
|
|
402
|
-
"title": "Set up NocoBase
|
|
402
|
+
"title": "Set up NocoBase",
|
|
403
403
|
"appNameRequiredWhenSkipped": "Env name is required when prompts are skipped.",
|
|
404
404
|
"appNameEnvHelp": "Use `nb init --yes --env <envName>` to continue.",
|
|
405
405
|
"resumeEnvRequired": "Env name is required when resuming setup.",
|
|
@@ -437,9 +437,9 @@
|
|
|
437
437
|
}
|
|
438
438
|
},
|
|
439
439
|
"webUi": {
|
|
440
|
-
"pageTitle": "Set up NocoBase
|
|
441
|
-
"documentHeading": "Set up NocoBase
|
|
442
|
-
"documentHint": "Install a new app, manage
|
|
440
|
+
"pageTitle": "Set up NocoBase",
|
|
441
|
+
"documentHeading": "Set up NocoBase",
|
|
442
|
+
"documentHint": "Install a new app, manage an existing one, or connect a remote app. You can use it directly or let a coding agent access it later.",
|
|
443
443
|
"gettingStarted": {
|
|
444
444
|
"title": "Getting started",
|
|
445
445
|
"description": "Choose whether to install a new app, manage a local app, or connect a remote app."
|
package/dist/locale/zh-CN.json
CHANGED
|
@@ -399,7 +399,7 @@
|
|
|
399
399
|
"envExists": "Env \"{{envName}}\" 已存在,请换一个 env name。"
|
|
400
400
|
},
|
|
401
401
|
"messages": {
|
|
402
|
-
"title": "
|
|
402
|
+
"title": "配置 NocoBase",
|
|
403
403
|
"appNameRequiredWhenSkipped": "跳过 prompts 时必须提供 Env name。",
|
|
404
404
|
"appNameEnvHelp": "请使用 `nb init --yes --env <envName>` 继续。",
|
|
405
405
|
"resumeEnvRequired": "恢复安装时必须提供 Env name。",
|
|
@@ -437,9 +437,9 @@
|
|
|
437
437
|
}
|
|
438
438
|
},
|
|
439
439
|
"webUi": {
|
|
440
|
-
"pageTitle": "
|
|
441
|
-
"documentHeading": "
|
|
442
|
-
"documentHint": "
|
|
440
|
+
"pageTitle": "配置 NocoBase",
|
|
441
|
+
"documentHeading": "配置 NocoBase",
|
|
442
|
+
"documentHint": "安装一个新的应用、管理已有应用,或连接远程应用。你可以直接使用它,也可以稍后让 coding agent 访问它。",
|
|
443
443
|
"gettingStarted": {
|
|
444
444
|
"title": "开始设置",
|
|
445
445
|
"description": "选择新安装、本机接管,或远程连接。"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/cli",
|
|
3
|
-
"version": "2.2.0-
|
|
3
|
+
"version": "2.2.0-beta.2",
|
|
4
4
|
"description": "NocoBase Command Line Tool",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/generated/command-registry.js",
|
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
"keywords": [],
|
|
13
13
|
"author": "",
|
|
14
14
|
"license": "Apache-2.0",
|
|
15
|
+
"files": [
|
|
16
|
+
"bin",
|
|
17
|
+
"dist",
|
|
18
|
+
"nocobase-ctl.config.json"
|
|
19
|
+
],
|
|
15
20
|
"bin": {
|
|
16
21
|
"nb": "./bin/run.js"
|
|
17
22
|
},
|
|
@@ -138,5 +143,5 @@
|
|
|
138
143
|
"type": "git",
|
|
139
144
|
"url": "git+https://github.com/nocobase/nocobase.git"
|
|
140
145
|
},
|
|
141
|
-
"gitHead": "
|
|
146
|
+
"gitHead": "2fe3e6a86fc1d0cd039349a68b2e4d1d6945ce45"
|
|
142
147
|
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# Rendered by `nb env proxy`.
|
|
2
|
-
# Context:
|
|
3
|
-
# publicBasePath={{publicBasePath}}
|
|
4
|
-
# apiBasePath={{apiBasePath}}
|
|
5
|
-
# wsPath={{wsPath}}
|
|
6
|
-
# v2PublicPath={{v2PublicPath}}
|
|
7
|
-
# backendUrl={{backendUrl}}
|
|
8
|
-
# snippetsDir={{snippetsDir}}
|
|
9
|
-
# uploadsDir={{uploadsDir}}
|
|
10
|
-
# distRootDir={{distRootDir}}
|
|
11
|
-
# entryDir={{entryDir}}
|
|
12
|
-
# publicDir={{publicDir}}
|
|
13
|
-
|
|
14
|
-
server {
|
|
15
|
-
listen 80;
|
|
16
|
-
server_name _;
|
|
17
|
-
|
|
18
|
-
# Add custom directives or locations above the managed block as needed.
|
|
19
|
-
|
|
20
|
-
{{managedConfigBlock}}
|
|
21
|
-
|
|
22
|
-
# Add custom directives or locations below the managed block as needed.
|
|
23
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
gzip on;
|
|
2
|
-
gzip_types
|
|
3
|
-
text/plain
|
|
4
|
-
text/css
|
|
5
|
-
text/xml
|
|
6
|
-
text/markdown
|
|
7
|
-
text/javascript
|
|
8
|
-
application/javascript
|
|
9
|
-
application/json
|
|
10
|
-
application/manifest+json
|
|
11
|
-
application/atom+xml
|
|
12
|
-
application/rss+xml
|
|
13
|
-
application/xml
|
|
14
|
-
application/xml+rss
|
|
15
|
-
application/xhtml+xml
|
|
16
|
-
application/wasm
|
|
17
|
-
image/svg+xml;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
log_format apm '"$time_local" client=$remote_addr '
|
|
2
|
-
'method=$request_method request="$request" '
|
|
3
|
-
'request_length=$request_length '
|
|
4
|
-
'status=$status bytes_sent=$bytes_sent '
|
|
5
|
-
'body_bytes_sent=$body_bytes_sent '
|
|
6
|
-
'referer=$http_referer '
|
|
7
|
-
'user_agent="$http_user_agent" '
|
|
8
|
-
'upstream_addr=$upstream_addr '
|
|
9
|
-
'upstream_status=$upstream_status '
|
|
10
|
-
'request_time=$request_time '
|
|
11
|
-
'upstream_response_time=$upstream_response_time '
|
|
12
|
-
'upstream_connect_time=$upstream_connect_time '
|
|
13
|
-
'upstream_header_time=$upstream_header_time';
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
map $http_upgrade $connection_upgrade {
|
|
2
|
-
default upgrade;
|
|
3
|
-
"" close;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
map $http_x_forwarded_proto $upstream_x_forwarded_proto {
|
|
7
|
-
default $http_x_forwarded_proto;
|
|
8
|
-
"" $scheme;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
map $http_host $final_host {
|
|
12
|
-
default $http_host;
|
|
13
|
-
"" $host;
|
|
14
|
-
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
types {
|
|
2
|
-
text/html html htm shtml;
|
|
3
|
-
text/css css;
|
|
4
|
-
text/xml xml;
|
|
5
|
-
image/gif gif;
|
|
6
|
-
image/jpeg jpeg jpg;
|
|
7
|
-
application/javascript js mjs;
|
|
8
|
-
application/atom+xml atom;
|
|
9
|
-
application/rss+xml rss;
|
|
10
|
-
|
|
11
|
-
text/mathml mml;
|
|
12
|
-
text/plain txt;
|
|
13
|
-
text/vnd.sun.j2me.app-descriptor jad;
|
|
14
|
-
text/vnd.wap.wml wml;
|
|
15
|
-
text/x-component htc;
|
|
16
|
-
|
|
17
|
-
image/avif avif;
|
|
18
|
-
image/png png;
|
|
19
|
-
image/svg+xml svg svgz;
|
|
20
|
-
image/tiff tif tiff;
|
|
21
|
-
image/vnd.wap.wbmp wbmp;
|
|
22
|
-
image/webp webp;
|
|
23
|
-
image/x-icon ico;
|
|
24
|
-
image/x-jng jng;
|
|
25
|
-
image/x-ms-bmp bmp;
|
|
26
|
-
|
|
27
|
-
font/woff woff;
|
|
28
|
-
font/woff2 woff2;
|
|
29
|
-
|
|
30
|
-
application/java-archive jar war ear;
|
|
31
|
-
application/json json;
|
|
32
|
-
application/mac-binhex40 hqx;
|
|
33
|
-
application/msword doc;
|
|
34
|
-
application/pdf pdf;
|
|
35
|
-
application/postscript ps eps ai;
|
|
36
|
-
application/rtf rtf;
|
|
37
|
-
application/vnd.apple.mpegurl m3u8;
|
|
38
|
-
application/vnd.google-earth.kml+xml kml;
|
|
39
|
-
application/vnd.google-earth.kmz kmz;
|
|
40
|
-
application/vnd.ms-excel xls;
|
|
41
|
-
application/vnd.ms-fontobject eot;
|
|
42
|
-
application/vnd.ms-powerpoint ppt;
|
|
43
|
-
application/vnd.oasis.opendocument.graphics odg;
|
|
44
|
-
application/vnd.oasis.opendocument.presentation odp;
|
|
45
|
-
application/vnd.oasis.opendocument.spreadsheet ods;
|
|
46
|
-
application/vnd.oasis.opendocument.text odt;
|
|
47
|
-
application/vnd.openxmlformats-officedocument.presentationml.presentation
|
|
48
|
-
pptx;
|
|
49
|
-
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
|
|
50
|
-
xlsx;
|
|
51
|
-
application/vnd.openxmlformats-officedocument.wordprocessingml.document
|
|
52
|
-
docx;
|
|
53
|
-
application/vnd.wap.wmlc wmlc;
|
|
54
|
-
application/wasm wasm;
|
|
55
|
-
application/x-7z-compressed 7z;
|
|
56
|
-
application/x-cocoa cco;
|
|
57
|
-
application/x-java-archive-diff jardiff;
|
|
58
|
-
application/x-java-jnlp-file jnlp;
|
|
59
|
-
application/x-makeself run;
|
|
60
|
-
application/x-perl pl pm;
|
|
61
|
-
application/x-pilot prc pdb;
|
|
62
|
-
application/x-rar-compressed rar;
|
|
63
|
-
application/x-redhat-package-manager rpm;
|
|
64
|
-
application/x-sea sea;
|
|
65
|
-
application/x-shockwave-flash swf;
|
|
66
|
-
application/x-stuffit sit;
|
|
67
|
-
application/x-tcl tcl tk;
|
|
68
|
-
application/x-x509-ca-cert der pem crt;
|
|
69
|
-
application/x-xpinstall xpi;
|
|
70
|
-
application/xhtml+xml xhtml;
|
|
71
|
-
application/xspf+xml xspf;
|
|
72
|
-
application/zip zip;
|
|
73
|
-
|
|
74
|
-
application/octet-stream bin exe dll;
|
|
75
|
-
application/octet-stream deb;
|
|
76
|
-
application/octet-stream dmg;
|
|
77
|
-
application/octet-stream iso img;
|
|
78
|
-
application/octet-stream msi msp msm;
|
|
79
|
-
|
|
80
|
-
audio/midi mid midi kar;
|
|
81
|
-
audio/mpeg mp3;
|
|
82
|
-
audio/ogg ogg;
|
|
83
|
-
audio/x-m4a m4a;
|
|
84
|
-
audio/x-realaudio ra;
|
|
85
|
-
|
|
86
|
-
video/3gpp 3gpp 3gp;
|
|
87
|
-
video/mp2t ts;
|
|
88
|
-
video/mp4 mp4;
|
|
89
|
-
video/mpeg mpeg mpg;
|
|
90
|
-
video/quicktime mov;
|
|
91
|
-
video/webm webm;
|
|
92
|
-
video/x-flv flv;
|
|
93
|
-
video/x-m4v m4v;
|
|
94
|
-
video/x-mng mng;
|
|
95
|
-
video/x-ms-asf asx asf;
|
|
96
|
-
video/x-ms-wmv wmv;
|
|
97
|
-
video/x-msvideo avi;
|
|
98
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
proxy_http_version 1.1;
|
|
2
|
-
|
|
3
|
-
proxy_set_header Upgrade $http_upgrade;
|
|
4
|
-
proxy_set_header Connection $connection_upgrade;
|
|
5
|
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
6
|
-
proxy_set_header X-Forwarded-Proto $upstream_x_forwarded_proto;
|
|
7
|
-
proxy_set_header Host $final_host;
|
|
8
|
-
proxy_set_header Referer $http_referer;
|
|
9
|
-
proxy_set_header User-Agent $http_user_agent;
|
|
10
|
-
|
|
11
|
-
add_header Cache-Control "no-cache, no-store" always;
|
|
12
|
-
proxy_cache_bypass $http_upgrade;
|
|
13
|
-
|
|
14
|
-
proxy_connect_timeout 600;
|
|
15
|
-
proxy_send_timeout 600;
|
|
16
|
-
proxy_read_timeout 600;
|
|
17
|
-
send_timeout 600;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
add_header Cache-Control "public" always;
|
|
2
|
-
add_header X-Content-Type-Options "nosniff" always;
|
|
3
|
-
|
|
4
|
-
access_log off;
|
|
5
|
-
autoindex off;
|
|
6
|
-
|
|
7
|
-
# Force potentially renderable uploaded files to download.
|
|
8
|
-
location ~* \.(?:htm|html|svg|svgz|xhtml)$ {
|
|
9
|
-
add_header Cache-Control "public" always;
|
|
10
|
-
add_header X-Content-Type-Options "nosniff" always;
|
|
11
|
-
add_header Content-Disposition "attachment" always;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
# Let Markdown files render as plain Markdown text.
|
|
15
|
-
location ~* \.md$ {
|
|
16
|
-
default_type text/markdown;
|
|
17
|
-
|
|
18
|
-
add_header Cache-Control "public" always;
|
|
19
|
-
add_header X-Content-Type-Options "nosniff" always;
|
|
20
|
-
add_header Content-Disposition "inline" always;
|
|
21
|
-
}
|
package/scripts/build.mjs
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { copyFileSync, mkdirSync, readdirSync, rmSync } from 'node:fs';
|
|
2
|
-
import { createRequire } from 'node:module';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { spawnSync } from 'node:child_process';
|
|
5
|
-
import { fileURLToPath } from 'node:url';
|
|
6
|
-
|
|
7
|
-
const require = createRequire(import.meta.url);
|
|
8
|
-
const scriptsDir = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
-
const packageRoot = path.resolve(scriptsDir, '..');
|
|
10
|
-
const distDir = path.join(packageRoot, 'dist');
|
|
11
|
-
const srcLocaleDir = path.join(packageRoot, 'src', 'locale');
|
|
12
|
-
const distLocaleDir = path.join(distDir, 'locale');
|
|
13
|
-
const tscBin = require.resolve('typescript/bin/tsc');
|
|
14
|
-
|
|
15
|
-
rmSync(distDir, { recursive: true, force: true });
|
|
16
|
-
|
|
17
|
-
const compile = spawnSync(process.execPath, [tscBin, '-p', path.join(packageRoot, 'tsconfig.json')], {
|
|
18
|
-
cwd: packageRoot,
|
|
19
|
-
stdio: 'inherit',
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
if (compile.status !== 0) {
|
|
23
|
-
process.exit(compile.status ?? 1);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
mkdirSync(distLocaleDir, { recursive: true });
|
|
27
|
-
|
|
28
|
-
for (const entry of readdirSync(srcLocaleDir, { withFileTypes: true })) {
|
|
29
|
-
if (!entry.isFile() || !entry.name.endsWith('.json')) {
|
|
30
|
-
continue;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
copyFileSync(path.join(srcLocaleDir, entry.name), path.join(distLocaleDir, entry.name));
|
|
34
|
-
}
|
package/scripts/clean.mjs
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { rmSync } from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { fileURLToPath } from 'node:url';
|
|
4
|
-
|
|
5
|
-
const scriptsDir = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
-
const packageRoot = path.resolve(scriptsDir, '..');
|
|
7
|
-
const distDir = path.join(packageRoot, 'dist');
|
|
8
|
-
|
|
9
|
-
rmSync(distDir, { recursive: true, force: true });
|
package/tsconfig.json
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "NodeNext",
|
|
5
|
-
"moduleResolution": "NodeNext",
|
|
6
|
-
"rewriteRelativeImportExtensions": true,
|
|
7
|
-
"rootDir": "src",
|
|
8
|
-
"outDir": "dist",
|
|
9
|
-
"declaration": false,
|
|
10
|
-
"resolveJsonModule": true,
|
|
11
|
-
"esModuleInterop": true,
|
|
12
|
-
"allowSyntheticDefaultImports": true,
|
|
13
|
-
"types": ["node"],
|
|
14
|
-
"skipLibCheck": true,
|
|
15
|
-
"strict": false
|
|
16
|
-
},
|
|
17
|
-
"include": ["src/**/*.ts"],
|
|
18
|
-
"exclude": ["src/**/__tests__/**"]
|
|
19
|
-
}
|