@appweaver/cli 1.0.0
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/LICENSE +1 -0
- package/README.md +7 -0
- package/build/build-command.d.ts +2 -0
- package/build/build-command.js +15 -0
- package/build/build-project.d.ts +8 -0
- package/build/build-project.js +19 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +18 -0
- package/generate/generate-command.d.ts +2 -0
- package/generate/generate-command.js +38 -0
- package/generate/generate-schema.d.ts +12 -0
- package/generate/generate-schema.js +475 -0
- package/generate/generate-types.d.ts +10 -0
- package/generate/generate-types.js +86 -0
- package/generate/index.d.ts +3 -0
- package/generate/index.js +19 -0
- package/migrate/index.d.ts +1 -0
- package/migrate/index.js +17 -0
- package/migrate/migrate-command.d.ts +2 -0
- package/migrate/migrate-command.js +13 -0
- package/migration/index.d.ts +1 -0
- package/migration/index.js +17 -0
- package/migration/migration-command.d.ts +2 -0
- package/migration/migration-command.js +34 -0
- package/openapi/index.d.ts +1 -0
- package/openapi/index.js +17 -0
- package/openapi/openapi-command.d.ts +2 -0
- package/openapi/openapi-command.js +46 -0
- package/package.json +56 -0
- package/seed/index.d.ts +1 -0
- package/seed/index.js +17 -0
- package/seed/seed-command.d.ts +2 -0
- package/seed/seed-command.js +33 -0
- package/skill/GUIDELINES.md +298 -0
- package/skill/SKILL.md +593 -0
- package/skill/references/cache.md +207 -0
- package/skill/references/cli.md +213 -0
- package/skill/references/client.md +507 -0
- package/skill/references/configuration.md +402 -0
- package/skill/references/database.md +134 -0
- package/skill/references/dependency-injection.md +214 -0
- package/skill/references/events.md +152 -0
- package/skill/references/mailer.md +235 -0
- package/skill/references/queue.md +196 -0
- package/skill/references/resources.md +961 -0
- package/skill/references/scheduler.md +184 -0
- package/skill/references/security.md +694 -0
- package/skill/references/storage.md +251 -0
- package/start/index.d.ts +2 -0
- package/start/index.js +18 -0
- package/start/start-command.d.ts +2 -0
- package/start/start-command.js +17 -0
- package/start/start-project.d.ts +8 -0
- package/start/start-project.js +147 -0
- package/testing/index.d.ts +1 -0
- package/testing/index.js +17 -0
- package/testing/testing-command.d.ts +2 -0
- package/testing/testing-command.js +96 -0
- package/update/index.d.ts +2 -0
- package/update/index.js +18 -0
- package/update/update-command.d.ts +2 -0
- package/update/update-command.js +84 -0
- package/update/update-packages.d.ts +10 -0
- package/update/update-packages.js +45 -0
- package/update/update-skill.d.ts +8 -0
- package/update/update-skill.js +93 -0
- package/utils/index.d.ts +3 -0
- package/utils/index.js +19 -0
- package/utils/loader-util.d.ts +29 -0
- package/utils/loader-util.js +132 -0
- package/utils/path-util.d.ts +41 -0
- package/utils/path-util.js +98 -0
- package/utils/process-util.d.ts +39 -0
- package/utils/process-util.js +92 -0
- package/weaver.d.ts +2 -0
- package/weaver.js +53 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updateCommand = updateCommand;
|
|
4
|
+
const common_1 = require("@appweaver/common");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
const update_packages_1 = require("./update-packages");
|
|
7
|
+
const update_skill_1 = require("./update-skill");
|
|
8
|
+
function updateCommand(program) {
|
|
9
|
+
program
|
|
10
|
+
.command('update')
|
|
11
|
+
.alias('u')
|
|
12
|
+
.description('Update the Appweaver packages.')
|
|
13
|
+
.argument('[packages...]', 'A list of packages to update (e.g. @appweaver/core @appweaver/cli).' +
|
|
14
|
+
'Defaults to all currently installed @appweaver/* packages.')
|
|
15
|
+
.option('--targetVersion [targetVersion]', 'The version to update the packages.', 'latest')
|
|
16
|
+
.option('--noSkill', 'Skip updating AI agents skill files in the current project.')
|
|
17
|
+
.option('-f, --force', 'Force update despite peerDependency version mismatches.')
|
|
18
|
+
.option('--verbose', 'Print verbose output.')
|
|
19
|
+
.action(async (packages, _, command) => {
|
|
20
|
+
const quiet = !command.getOptionValue('verbose');
|
|
21
|
+
const force = command.getOptionValue('force');
|
|
22
|
+
const updateSkill = !command.getOptionValue('noSkill');
|
|
23
|
+
const targetVersion = command.getOptionValue('targetVersion');
|
|
24
|
+
// Load all currently installed packages
|
|
25
|
+
const installedPackages = {};
|
|
26
|
+
try {
|
|
27
|
+
const pkg = await (0, utils_1.loadLocalPackageJson)();
|
|
28
|
+
const allDeps = {
|
|
29
|
+
...(pkg.dependencies ?? {}),
|
|
30
|
+
...(pkg.devDependencies ?? {})
|
|
31
|
+
};
|
|
32
|
+
for (const [name, version] of Object.entries(allDeps)) {
|
|
33
|
+
installedPackages[name] = version;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
if (!quiet) {
|
|
38
|
+
console.error(e);
|
|
39
|
+
}
|
|
40
|
+
console.error('Unable to open package.json file');
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
// Create a list of packages to update (without version suffix)
|
|
44
|
+
const packagesToUpdate = [];
|
|
45
|
+
if (packages.length > 0) {
|
|
46
|
+
packagesToUpdate.push(...packages.map((p) => {
|
|
47
|
+
const at = p.lastIndexOf('@');
|
|
48
|
+
return at > 0 ? p.slice(0, at) : p;
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
packagesToUpdate.push(...Object.keys(installedPackages));
|
|
53
|
+
}
|
|
54
|
+
// This command should only update Appweaver packages
|
|
55
|
+
const appweaverPackages = packagesToUpdate.filter((p) => p.startsWith('@appweaver/'));
|
|
56
|
+
if (appweaverPackages.length === 0) {
|
|
57
|
+
console.log(`No @appweaver packages found for update.`);
|
|
58
|
+
process.exit(0);
|
|
59
|
+
}
|
|
60
|
+
// Check if there are already greater versions installed for each package
|
|
61
|
+
if (targetVersion !== 'latest' && !quiet) {
|
|
62
|
+
for (const packageName of packagesToUpdate) {
|
|
63
|
+
const installedPackageVersion = installedPackages[packageName];
|
|
64
|
+
if (installedPackageVersion) {
|
|
65
|
+
const cleanInstalled = installedPackageVersion.replace(/^[^0-9]*/, '');
|
|
66
|
+
if ((0, common_1.compareVersions)(cleanInstalled, targetVersion) > 0) {
|
|
67
|
+
console.warn(`${packageName} already has greater version ${cleanInstalled} than the requested version ${targetVersion}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const status = await (0, update_packages_1.updatePackages)(appweaverPackages, targetVersion, force, quiet);
|
|
73
|
+
if (status === 0) {
|
|
74
|
+
if (updateSkill) {
|
|
75
|
+
await (0, update_skill_1.updateSkillFiles)(quiet);
|
|
76
|
+
}
|
|
77
|
+
console.log(`Successfully updated packages to ${targetVersion} version.`);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
console.error('Update did not complete successfully. Use --verbose flag to see error details.');
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Updates a list of packages to the specified version.
|
|
3
|
+
*
|
|
4
|
+
* @param {string[]} packages - An array of package names to be updated.
|
|
5
|
+
* @param {string} version - The version to which the packages should be updated.
|
|
6
|
+
* @param {boolean} [force=false] - Whether to forcibly update the packages, overriding any potential constraints.
|
|
7
|
+
* @param {boolean} [quiet=true] - Whether to suppress output logs during the update process.
|
|
8
|
+
* @return {Promise<number>} Resolves to the number of packages successfully updated.
|
|
9
|
+
*/
|
|
10
|
+
export declare function updatePackages(packages: string[], version: string, force?: boolean, quiet?: boolean): Promise<number>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updatePackages = updatePackages;
|
|
4
|
+
const common_1 = require("@appweaver/common");
|
|
5
|
+
const utils_1 = require("../utils");
|
|
6
|
+
/**
|
|
7
|
+
* Updates a list of packages to the specified version.
|
|
8
|
+
*
|
|
9
|
+
* @param {string[]} packages - An array of package names to be updated.
|
|
10
|
+
* @param {string} version - The version to which the packages should be updated.
|
|
11
|
+
* @param {boolean} [force=false] - Whether to forcibly update the packages, overriding any potential constraints.
|
|
12
|
+
* @param {boolean} [quiet=true] - Whether to suppress output logs during the update process.
|
|
13
|
+
* @return {Promise<number>} Resolves to the number of packages successfully updated.
|
|
14
|
+
*/
|
|
15
|
+
async function updatePackages(packages, version, force = false, quiet = true) {
|
|
16
|
+
const packagesWithVersion = packages.map((p) => `${p}@${version}`);
|
|
17
|
+
if ((0, utils_1.isBunProcess)() && common_1.config.APP_RUNTIME === common_1.Runtime.Bun) {
|
|
18
|
+
return updateBunPackages(packagesWithVersion, quiet);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
return updateNodePackages(packagesWithVersion, force, quiet);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Updates the specified Node.js packages using npm.
|
|
26
|
+
*
|
|
27
|
+
* @param {string[]} packages - An array of package names to update.
|
|
28
|
+
* @param {boolean} force - A flag indicating whether to force the update by ignoring peer dependencies.
|
|
29
|
+
* @param {boolean} quiet - A flag indicating whether to suppress output during the update process.
|
|
30
|
+
* @return {Promise<number>} A promise that resolves with the exit code of the npm process.
|
|
31
|
+
*/
|
|
32
|
+
async function updateNodePackages(packages, force, quiet) {
|
|
33
|
+
return (0, utils_1.runProcess)('npm', ['install', ...packages, ...(force ? ['--legacy-peer-deps'] : [])], { quiet });
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Updates the specified Bun packages by adding them to the project.
|
|
37
|
+
*
|
|
38
|
+
* @param {string[]} packages - An array of package names to update or add.
|
|
39
|
+
* @param {boolean} quiet - A flag to suppress output if set to true.
|
|
40
|
+
* @return {Promise<number>} A promise that resolves to the exit code of the process.
|
|
41
|
+
*/
|
|
42
|
+
async function updateBunPackages(packages, quiet) {
|
|
43
|
+
// Bun already handles peerDependency version mismatch without error
|
|
44
|
+
return (0, utils_1.runProcess)('bun', ['add', ...packages], { quiet });
|
|
45
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Updates skill files and AI guidelines in the project by copying the skill directory
|
|
3
|
+
* to specified agent directories and updating references in guideline files.
|
|
4
|
+
*
|
|
5
|
+
* @param {boolean} quiet - If true, suppresses logging output; otherwise, logs actions performed.
|
|
6
|
+
* @return {Promise<void>} A promise that resolves when the update process is complete.
|
|
7
|
+
*/
|
|
8
|
+
export declare function updateSkillFiles(quiet: boolean): Promise<void>;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.updateSkillFiles = updateSkillFiles;
|
|
7
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
8
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
/**
|
|
11
|
+
* Updates skill files and AI guidelines in the project by copying the skill directory
|
|
12
|
+
* to specified agent directories and updating references in guideline files.
|
|
13
|
+
*
|
|
14
|
+
* @param {boolean} quiet - If true, suppresses logging output; otherwise, logs actions performed.
|
|
15
|
+
* @return {Promise<void>} A promise that resolves when the update process is complete.
|
|
16
|
+
*/
|
|
17
|
+
async function updateSkillFiles(quiet) {
|
|
18
|
+
const projectDir = process.cwd();
|
|
19
|
+
const skillDir = node_path_1.default.join(__dirname, '..', 'skill');
|
|
20
|
+
if (!(await exists(skillDir))) {
|
|
21
|
+
if (!quiet) {
|
|
22
|
+
console.warn('Skill directory not found, skipping skill file update.\n');
|
|
23
|
+
}
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const guidelinesFilePath = node_path_1.default.join(skillDir, 'GUIDELINES.md');
|
|
27
|
+
const guidelinesContents = await promises_1.default.readFile(guidelinesFilePath, 'utf8');
|
|
28
|
+
const foundAgentDirs = [];
|
|
29
|
+
for (const agentDir of [
|
|
30
|
+
'.claude',
|
|
31
|
+
'.junie',
|
|
32
|
+
'.kiro',
|
|
33
|
+
'.pi',
|
|
34
|
+
'.github',
|
|
35
|
+
'.opencode',
|
|
36
|
+
'.agents'
|
|
37
|
+
]) {
|
|
38
|
+
const agentDirPath = node_path_1.default.join(projectDir, agentDir);
|
|
39
|
+
if (!(await exists(agentDirPath))) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
foundAgentDirs.push(agentDir);
|
|
43
|
+
// Copy skill directory to {agentDir}/skills/appweaver/
|
|
44
|
+
const skillDestPath = node_path_1.default.join(agentDirPath, 'skills', 'appweaver');
|
|
45
|
+
await promises_1.default.cp(skillDir, skillDestPath, {
|
|
46
|
+
recursive: true,
|
|
47
|
+
filter: (src) => !src.endsWith('GUIDELINES.md')
|
|
48
|
+
});
|
|
49
|
+
if (!quiet) {
|
|
50
|
+
console.log(`Updated skill files in ${node_path_1.default.join(agentDir, 'skills', 'appweaver')}\n`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
let firstAgentDir = foundAgentDirs[0];
|
|
54
|
+
for (const guidelinesFile of ['AGENTS.md', 'CLAUDE.md']) {
|
|
55
|
+
const guidelinesFilePath = node_path_1.default.join(projectDir, guidelinesFile);
|
|
56
|
+
// Update only agent guidelines files that already exist
|
|
57
|
+
if (!(await exists(guidelinesFilePath))) {
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
// If no agent-specific dir was discovered, create new generic .agents dir
|
|
61
|
+
if (!firstAgentDir) {
|
|
62
|
+
firstAgentDir = '.agents';
|
|
63
|
+
const skillDestPath = node_path_1.default.join(node_path_1.default.join(projectDir, firstAgentDir), 'skills', 'appweaver');
|
|
64
|
+
await promises_1.default.cp(skillDir, skillDestPath, {
|
|
65
|
+
recursive: true,
|
|
66
|
+
filter: (src) => !src.endsWith('GUIDELINES.md')
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
// Replace guideline file path references with path references in first
|
|
70
|
+
// discovered agents dir
|
|
71
|
+
const referencesPath = node_path_1.default
|
|
72
|
+
.join(firstAgentDir, 'skills', 'appweaver', 'references')
|
|
73
|
+
.replace(/\\/g, '/');
|
|
74
|
+
const guidelinesContent = guidelinesContents.replace(/(\[.+]\()references\/(.+\))/g, `$1${referencesPath}/$2`);
|
|
75
|
+
await promises_1.default.writeFile(guidelinesFilePath, guidelinesContent, {
|
|
76
|
+
encoding: 'utf8'
|
|
77
|
+
});
|
|
78
|
+
if (!quiet) {
|
|
79
|
+
console.log(`Updated AI guidelines file ${guidelinesFile}\n`);
|
|
80
|
+
}
|
|
81
|
+
// Update only the first found guidelines file
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async function exists(filePath) {
|
|
86
|
+
try {
|
|
87
|
+
await promises_1.default.access(filePath, node_fs_1.default.constants.F_OK);
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}
|
package/utils/index.d.ts
ADDED
package/utils/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./loader-util"), exports);
|
|
18
|
+
__exportStar(require("./path-util"), exports);
|
|
19
|
+
__exportStar(require("./process-util"), exports);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ResourceModel } from '@appweaver/common';
|
|
2
|
+
/**
|
|
3
|
+
* Loads and parses the `package.json` file located in the CLI project package directory.
|
|
4
|
+
* The function attempts to locate the `package.json` file in one of two
|
|
5
|
+
* predefined directories relative to the current module's directory.
|
|
6
|
+
* If the file is found, its contents are read and parsed into a JavaScript object.
|
|
7
|
+
*
|
|
8
|
+
* @return {Record<string, Object>} The parsed contents of the `package.json` file as a key-value object.
|
|
9
|
+
*/
|
|
10
|
+
export declare function loadCliPackageJson(): Record<string, any>;
|
|
11
|
+
/**
|
|
12
|
+
* Loads the `package.json` file from the local working directory and parses its content into a JavaScript object.
|
|
13
|
+
*
|
|
14
|
+
* @return {Promise<Record<string, Object>>} A promise that resolves to an object representing the contents of the
|
|
15
|
+
* `package.json` file, where keys and values are strings.
|
|
16
|
+
*/
|
|
17
|
+
export declare function loadLocalPackageJson(): Promise<Record<string, any>>;
|
|
18
|
+
/**
|
|
19
|
+
* Loads and registers resource models from the specified file pattern.
|
|
20
|
+
*
|
|
21
|
+
* This method scans for model files that match the given pattern,
|
|
22
|
+
* imports them, and checks if they conform to the resource model schema.
|
|
23
|
+
* Valid models are added to the returned collection.
|
|
24
|
+
*
|
|
25
|
+
* @param {string} [modelPattern] - The glob pattern used to locate model files. The default value is used from config.
|
|
26
|
+
* @return {Promise<Record<string, ResourceModel>>} A promise resolving to an object containing the loaded resource models,
|
|
27
|
+
* where the keys are the model names and the values are the associated ResourceModel objects.
|
|
28
|
+
*/
|
|
29
|
+
export declare function loadModels(modelPattern: string): Promise<Record<string, ResourceModel>>;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.loadCliPackageJson = loadCliPackageJson;
|
|
40
|
+
exports.loadLocalPackageJson = loadLocalPackageJson;
|
|
41
|
+
exports.loadModels = loadModels;
|
|
42
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
43
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
44
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
45
|
+
const glob_1 = require("glob");
|
|
46
|
+
const ts_node_1 = require("ts-node");
|
|
47
|
+
const common_1 = require("@appweaver/common");
|
|
48
|
+
/**
|
|
49
|
+
* Loads and parses the `package.json` file located in the CLI project package directory.
|
|
50
|
+
* The function attempts to locate the `package.json` file in one of two
|
|
51
|
+
* predefined directories relative to the current module's directory.
|
|
52
|
+
* If the file is found, its contents are read and parsed into a JavaScript object.
|
|
53
|
+
*
|
|
54
|
+
* @return {Record<string, Object>} The parsed contents of the `package.json` file as a key-value object.
|
|
55
|
+
*/
|
|
56
|
+
function loadCliPackageJson() {
|
|
57
|
+
const pkgPath = node_path_1.default.join(__dirname, '../package.json');
|
|
58
|
+
const pkgContent = node_fs_1.default.readFileSync(pkgPath, 'utf8');
|
|
59
|
+
return JSON.parse(pkgContent);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Loads the `package.json` file from the local working directory and parses its content into a JavaScript object.
|
|
63
|
+
*
|
|
64
|
+
* @return {Promise<Record<string, Object>>} A promise that resolves to an object representing the contents of the
|
|
65
|
+
* `package.json` file, where keys and values are strings.
|
|
66
|
+
*/
|
|
67
|
+
async function loadLocalPackageJson() {
|
|
68
|
+
const pkgPath = node_path_1.default.join(process.cwd(), 'package.json');
|
|
69
|
+
const pkgContent = await promises_1.default.readFile(pkgPath, 'utf-8');
|
|
70
|
+
return JSON.parse(pkgContent);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Loads and registers resource models from the specified file pattern.
|
|
74
|
+
*
|
|
75
|
+
* This method scans for model files that match the given pattern,
|
|
76
|
+
* imports them, and checks if they conform to the resource model schema.
|
|
77
|
+
* Valid models are added to the returned collection.
|
|
78
|
+
*
|
|
79
|
+
* @param {string} [modelPattern] - The glob pattern used to locate model files. The default value is used from config.
|
|
80
|
+
* @return {Promise<Record<string, ResourceModel>>} A promise resolving to an object containing the loaded resource models,
|
|
81
|
+
* where the keys are the model names and the values are the associated ResourceModel objects.
|
|
82
|
+
*/
|
|
83
|
+
async function loadModels(modelPattern) {
|
|
84
|
+
const cwd = process.cwd();
|
|
85
|
+
(0, ts_node_1.register)({
|
|
86
|
+
transpileOnly: true,
|
|
87
|
+
compilerOptions: {
|
|
88
|
+
module: 'CommonJS'
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
const models = {};
|
|
92
|
+
const modelPaths = [];
|
|
93
|
+
// Add project files using a pattern
|
|
94
|
+
const projectModelPaths = await (0, glob_1.glob)(modelPattern, { cwd, absolute: true });
|
|
95
|
+
// Sort is needed since glob returns files in non-deterministic order
|
|
96
|
+
projectModelPaths.sort();
|
|
97
|
+
modelPaths.push(...projectModelPaths);
|
|
98
|
+
// Add exported core module resources
|
|
99
|
+
modelPaths.push('@appweaver/core/resources');
|
|
100
|
+
// Add additional modules from config
|
|
101
|
+
for (const module of common_1.config.APP_AUTOLOAD_MODULES) {
|
|
102
|
+
modelPaths.push(module);
|
|
103
|
+
}
|
|
104
|
+
for (const modelPath of modelPaths) {
|
|
105
|
+
let modelExport;
|
|
106
|
+
try {
|
|
107
|
+
// Clear cache to ensure fresh model data
|
|
108
|
+
delete require.cache[require.resolve(modelPath)];
|
|
109
|
+
modelExport = await Promise.resolve(`${modelPath}`).then(s => __importStar(require(s)));
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
console.log('Cannot load module:', modelPath, '\nError:', error, '\nSkipping...');
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
const modelSchema = modelExport.default || modelExport;
|
|
116
|
+
// Add only exports that satisfy the resource model schema requirements
|
|
117
|
+
if ((0, common_1.isResourceModel)(modelSchema)) {
|
|
118
|
+
models[modelSchema.name] = modelSchema;
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
for (const maybeSchema of Object.values(modelSchema)) {
|
|
122
|
+
if ((0, common_1.isResourceModel)(maybeSchema)) {
|
|
123
|
+
models[maybeSchema.name] = maybeSchema;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (Object.keys(models).length === 0) {
|
|
129
|
+
console.log('No resource models exports found matching pattern:', modelPattern);
|
|
130
|
+
}
|
|
131
|
+
return models;
|
|
132
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Computes the relative path from the directory of the first path to the other path.
|
|
3
|
+
*
|
|
4
|
+
* @param {string} firstPath - The base path used to calculate the relative path.
|
|
5
|
+
* @param {string} otherPath - The target path for which the relative path will be calculated.
|
|
6
|
+
* @return {string} The relative path from the `firstPath` directory to `otherPath`, normalized with forward slashes.
|
|
7
|
+
*/
|
|
8
|
+
export declare function relativePathFrom(firstPath: string, otherPath: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Asserts that the `childPath` is located inside the `basePath`. If the condition
|
|
11
|
+
* is not met, logs the specified error message and terminates the process.
|
|
12
|
+
*
|
|
13
|
+
* @param basePath The base directory path to validate against.
|
|
14
|
+
* @param childPath The path to validate as being inside the `basePath`.
|
|
15
|
+
* @param message The error message to log if the assertion fails.
|
|
16
|
+
*/
|
|
17
|
+
export declare function assertPathInside(basePath: string, childPath: string, message: string): void;
|
|
18
|
+
/**
|
|
19
|
+
* Determines whether a given child path is located within a specific base path.
|
|
20
|
+
*
|
|
21
|
+
* @param {string} basePath - The base directory path to check against.
|
|
22
|
+
* @param {string} childPath - The child path to evaluate.
|
|
23
|
+
* @return {boolean} Returns true if the child path is inside the base path; otherwise, false.
|
|
24
|
+
*/
|
|
25
|
+
export declare function isPathInside(basePath: string, childPath: string): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Recursively removes a specified file or directory path.
|
|
28
|
+
*
|
|
29
|
+
* @param {string} path - The file or directory path to be removed.
|
|
30
|
+
* @param {boolean} [quiet=false] - If true, suppresses error logging when an error occurs.
|
|
31
|
+
* @return {Promise<boolean>} A promise that resolves to `true` if a path is removed, `false` otherwise.
|
|
32
|
+
*/
|
|
33
|
+
export declare function rimrafPath(path: string, quiet?: boolean): Promise<boolean>;
|
|
34
|
+
/**
|
|
35
|
+
* Ensures that the directory for the given file path exists. If the directory does not exist, it is created
|
|
36
|
+
* recursively.
|
|
37
|
+
*
|
|
38
|
+
* @param {string} filePath - The path of the file whose directory needs to be checked or created.
|
|
39
|
+
* @return {Promise<void>} A promise that resolves when the directory exists or has been successfully created.
|
|
40
|
+
*/
|
|
41
|
+
export declare function ensureDirExists(filePath: string): Promise<void>;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.relativePathFrom = relativePathFrom;
|
|
7
|
+
exports.assertPathInside = assertPathInside;
|
|
8
|
+
exports.isPathInside = isPathInside;
|
|
9
|
+
exports.rimrafPath = rimrafPath;
|
|
10
|
+
exports.ensureDirExists = ensureDirExists;
|
|
11
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
+
const promises_1 = __importDefault(require("node:fs/promises"));
|
|
13
|
+
const rimraf_1 = require("rimraf");
|
|
14
|
+
/**
|
|
15
|
+
* Computes the relative path from the directory of the first path to the other path.
|
|
16
|
+
*
|
|
17
|
+
* @param {string} firstPath - The base path used to calculate the relative path.
|
|
18
|
+
* @param {string} otherPath - The target path for which the relative path will be calculated.
|
|
19
|
+
* @return {string} The relative path from the `firstPath` directory to `otherPath`, normalized with forward slashes.
|
|
20
|
+
*/
|
|
21
|
+
function relativePathFrom(firstPath, otherPath) {
|
|
22
|
+
const schemaDir = node_path_1.default.dirname(node_path_1.default.resolve(firstPath));
|
|
23
|
+
const clientAbs = node_path_1.default.resolve(otherPath);
|
|
24
|
+
let rel = node_path_1.default.relative(schemaDir, clientAbs);
|
|
25
|
+
if (!rel.startsWith('.') && rel !== '') {
|
|
26
|
+
rel = `.${node_path_1.default.sep}${rel}`;
|
|
27
|
+
}
|
|
28
|
+
else if (rel === '') {
|
|
29
|
+
rel = '.';
|
|
30
|
+
}
|
|
31
|
+
return rel.replace(/\\/g, '/');
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Asserts that the `childPath` is located inside the `basePath`. If the condition
|
|
35
|
+
* is not met, logs the specified error message and terminates the process.
|
|
36
|
+
*
|
|
37
|
+
* @param basePath The base directory path to validate against.
|
|
38
|
+
* @param childPath The path to validate as being inside the `basePath`.
|
|
39
|
+
* @param message The error message to log if the assertion fails.
|
|
40
|
+
*/
|
|
41
|
+
function assertPathInside(basePath, childPath, message) {
|
|
42
|
+
if (!isPathInside(basePath, childPath)) {
|
|
43
|
+
console.error(message);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Determines whether a given child path is located within a specific base path.
|
|
49
|
+
*
|
|
50
|
+
* @param {string} basePath - The base directory path to check against.
|
|
51
|
+
* @param {string} childPath - The child path to evaluate.
|
|
52
|
+
* @return {boolean} Returns true if the child path is inside the base path; otherwise, false.
|
|
53
|
+
*/
|
|
54
|
+
function isPathInside(basePath, childPath) {
|
|
55
|
+
const base = node_path_1.default.resolve(basePath);
|
|
56
|
+
const child = node_path_1.default.resolve(childPath);
|
|
57
|
+
// Add a trailing separator so `/temp/dir2` is not matched by `/temp/dir`
|
|
58
|
+
const baseWithSep = base.endsWith(node_path_1.default.sep) ? base : base + node_path_1.default.sep;
|
|
59
|
+
return child.startsWith(baseWithSep);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Recursively removes a specified file or directory path.
|
|
63
|
+
*
|
|
64
|
+
* @param {string} path - The file or directory path to be removed.
|
|
65
|
+
* @param {boolean} [quiet=false] - If true, suppresses error logging when an error occurs.
|
|
66
|
+
* @return {Promise<boolean>} A promise that resolves to `true` if a path is removed, `false` otherwise.
|
|
67
|
+
*/
|
|
68
|
+
async function rimrafPath(path, quiet = false) {
|
|
69
|
+
try {
|
|
70
|
+
const result = await (0, rimraf_1.rimraf)(path, { maxRetries: 10, retryDelay: 100 });
|
|
71
|
+
if (!result && !quiet) {
|
|
72
|
+
console.error(`Unable to remove path: ${path}`);
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
if (!quiet) {
|
|
78
|
+
console.error(`Error removing path: ${path}`, error);
|
|
79
|
+
}
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Ensures that the directory for the given file path exists. If the directory does not exist, it is created
|
|
85
|
+
* recursively.
|
|
86
|
+
*
|
|
87
|
+
* @param {string} filePath - The path of the file whose directory needs to be checked or created.
|
|
88
|
+
* @return {Promise<void>} A promise that resolves when the directory exists or has been successfully created.
|
|
89
|
+
*/
|
|
90
|
+
async function ensureDirExists(filePath) {
|
|
91
|
+
const dirPath = node_path_1.default.resolve(node_path_1.default.dirname(filePath));
|
|
92
|
+
try {
|
|
93
|
+
await promises_1.default.access(dirPath, promises_1.default.constants.F_OK);
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
await promises_1.default.mkdir(dirPath, { recursive: true });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Executes a shell command with optional arguments and configuration parameters.
|
|
3
|
+
*
|
|
4
|
+
* @param {string} cmd - The command to execute.
|
|
5
|
+
* @param {string[]} [args=[]] - An array of arguments to pass to the command.
|
|
6
|
+
* @param {Object} [params={ quiet: false }] - Configurations for how the process should run.
|
|
7
|
+
* @param {boolean} [params.quiet=false] - If true, suppresses the process output.
|
|
8
|
+
* @param {AbortSignal} [params.signal] - Optional AbortSignal to terminate the running process.
|
|
9
|
+
* @return {Promise<number>} A promise that resolves with the exit code of the process or 1 on error.
|
|
10
|
+
*/
|
|
11
|
+
export declare function runProcess(cmd: string, args?: string[], params?: {
|
|
12
|
+
quiet?: boolean;
|
|
13
|
+
signal?: AbortSignal;
|
|
14
|
+
}): Promise<number>;
|
|
15
|
+
/**
|
|
16
|
+
* Verifies that the application's runtime environment matches the specified environment.
|
|
17
|
+
* Terminates the process with an error message if the environments do not match.
|
|
18
|
+
*
|
|
19
|
+
* @param {string} env - The expected environment (e.g., 'production', 'development').
|
|
20
|
+
* @param {string} message - The error message to display if the environment does not match.
|
|
21
|
+
*/
|
|
22
|
+
export declare function assertEnv(env: string, message: string): void;
|
|
23
|
+
/**
|
|
24
|
+
* Verifies that the application's runtime environment matches one of the specified environments.
|
|
25
|
+
* Terminates the process with an error message if the environment does not match any of the provided options.
|
|
26
|
+
*
|
|
27
|
+
* @param {string[]} envs - An array of expected environments (e.g., ['prod', 'dev', 'test']).
|
|
28
|
+
* @param {string} message - The error message to display if the environment does not match any of the provided options.
|
|
29
|
+
*/
|
|
30
|
+
export declare function assertEnvs(envs: string[], message: string): void;
|
|
31
|
+
/**
|
|
32
|
+
* Checks if the current environment is a Bun.js process.
|
|
33
|
+
*
|
|
34
|
+
* This method determines whether the global `Bun` object is defined,
|
|
35
|
+
* which indicates the code is running in a Bun.js runtime environment.
|
|
36
|
+
*
|
|
37
|
+
* @return {boolean} Returns `true` if the `Bun` object is defined, otherwise `false`.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isBunProcess(): boolean;
|