@researchdatabox/redbox-dev-tools 0.0.1-beta.8936
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 +255 -0
- package/bin/cli.js +3 -0
- package/bin/run-hook-mocha.js +3 -0
- package/bin/run-hook-tsc.js +3 -0
- package/bin/wrapper-webpack.js +145 -0
- package/config/tsconfig.base.json +16 -0
- package/dist/bin/run-hook-mocha.d.ts +1 -0
- package/dist/bin/run-hook-mocha.js +49 -0
- package/dist/bin/run-hook-tsc.d.ts +1 -0
- package/dist/bin/run-hook-tsc.js +19 -0
- package/dist/cli-parsers.d.ts +9 -0
- package/dist/cli-parsers.js +131 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +464 -0
- package/dist/commands/form-config.d.ts +5 -0
- package/dist/commands/form-config.js +194 -0
- package/dist/completion/index.d.ts +1 -0
- package/dist/completion/index.js +217 -0
- package/dist/generators/add-method.d.ts +27 -0
- package/dist/generators/add-method.js +235 -0
- package/dist/generators/angular-app.d.ts +24 -0
- package/dist/generators/angular-app.js +342 -0
- package/dist/generators/angular-service.d.ts +21 -0
- package/dist/generators/angular-service.js +154 -0
- package/dist/generators/controller.d.ts +40 -0
- package/dist/generators/controller.js +195 -0
- package/dist/generators/form-component.d.ts +46 -0
- package/dist/generators/form-component.js +906 -0
- package/dist/generators/form-field.d.ts +15 -0
- package/dist/generators/form-field.js +160 -0
- package/dist/generators/model.d.ts +42 -0
- package/dist/generators/model.js +206 -0
- package/dist/generators/service.d.ts +16 -0
- package/dist/generators/service.js +111 -0
- package/dist/runtime-resolver.d.ts +3 -0
- package/dist/runtime-resolver.js +27 -0
- package/dist/templates/hook-archetype.d.ts +12 -0
- package/dist/templates/hook-archetype.js +143 -0
- package/dist/testing.d.ts +7 -0
- package/dist/testing.js +53 -0
- package/dist/utils/config-helper.d.ts +71 -0
- package/dist/utils/config-helper.js +574 -0
- package/dist/utils/generator.d.ts +10 -0
- package/dist/utils/generator.js +68 -0
- package/dist/utils/hook-tsconfig.d.ts +9 -0
- package/dist/utils/hook-tsconfig.js +104 -0
- package/dist/utils/paths.d.ts +10 -0
- package/dist/utils/paths.js +60 -0
- package/index.js +4 -0
- package/package.json +85 -0
- package/runtime-resolver.d.ts +1 -0
- package/runtime-resolver.js +3 -0
- package/skills/redbox-angular-apps/SKILL.md +42 -0
- package/skills/redbox-angular-services/SKILL.md +29 -0
- package/skills/redbox-controllers/SKILL.md +65 -0
- package/skills/redbox-feature-design-planner/SKILL.md +169 -0
- package/skills/redbox-feature-implementation-review/SKILL.md +117 -0
- package/skills/redbox-form-components/SKILL.md +114 -0
- package/skills/redbox-form-config/SKILL.md +34 -0
- package/skills/redbox-hook-development/SKILL.md +66 -0
- package/skills/redbox-services/SKILL.md +54 -0
- package/skills/redbox-test-verification/SKILL.md +38 -0
- package/skills/redbox-testing/SKILL.md +64 -0
- package/skills/redbox-web-verification/SKILL.md +71 -0
- package/skills/redbox-web-verification/redbox-angular-apps/SKILL.md +48 -0
- package/skills/redbox-web-verification/redbox-angular-services/SKILL.md +30 -0
- package/skills/redbox-web-verification/redbox-controllers/SKILL.md +56 -0
- package/skills/redbox-web-verification/redbox-form-config/SKILL.md +29 -0
- package/skills/redbox-web-verification/redbox-hook-development/SKILL.md +61 -0
- package/skills/redbox-web-verification/redbox-services/SKILL.md +45 -0
- package/skills/redbox-web-verification/redbox-testing/SKILL.md +53 -0
- package/skills/redbox-web-verification/redbox-web-verification/SKILL.md +47 -0
- package/templates/hook-archetype/standard/.gitignore.hbs +4 -0
- package/templates/hook-archetype/standard/.npmignore.hbs +3 -0
- package/templates/hook-archetype/standard/.npmrc.hbs +6 -0
- package/templates/hook-archetype/standard/.nvmrc.hbs +1 -0
- package/templates/hook-archetype/standard/AGENTS.md.hbs +34 -0
- package/templates/hook-archetype/standard/Dockerfile.hbs +28 -0
- package/templates/hook-archetype/standard/README.md.hbs +39 -0
- package/templates/hook-archetype/standard/assets/fonts/.gitkeep +1 -0
- package/templates/hook-archetype/standard/language-defaults/.gitkeep +1 -0
- package/templates/hook-archetype/standard/package.json.hbs +40 -0
- package/templates/hook-archetype/standard/src/api/controllers/ExampleController.ts.hbs +21 -0
- package/templates/hook-archetype/standard/src/api/controllers/index.ts.hbs +23 -0
- package/templates/hook-archetype/standard/src/api/services/ExampleService.ts.hbs +22 -0
- package/templates/hook-archetype/standard/src/api/services/index.ts.hbs +23 -0
- package/templates/hook-archetype/standard/src/config/brandingConfigurationDefaults.ts.hbs +9 -0
- package/templates/hook-archetype/standard/src/config/reusableFormDefinitions.ts.hbs +6 -0
- package/templates/hook-archetype/standard/src/form-config/default-1.0-draft.ts.hbs +20 -0
- package/templates/hook-archetype/standard/src/form-config/index.ts.hbs +8 -0
- package/templates/hook-archetype/standard/src/index.ts.hbs +55 -0
- package/templates/hook-archetype/standard/support/bootstrap-data/.gitkeep +1 -0
- package/templates/hook-archetype/standard/support/development/docker-compose.yml.hbs +75 -0
- package/templates/hook-archetype/standard/support/integration-testing/docker-compose.mocha.yml.hbs +84 -0
- package/templates/hook-archetype/standard/support/integration-testing/run-mocha-hook.sh.hbs +9 -0
- package/templates/hook-archetype/standard/test/integration/hook-registration.test.ts.hbs +13 -0
- package/templates/hook-archetype/standard/test/support/globals.ts.hbs +40 -0
- package/templates/hook-archetype/standard/test/tsconfig.json.hbs +8 -0
- package/templates/hook-archetype/standard/test/unit/.mocharc.cjs.hbs +9 -0
- package/templates/hook-archetype/standard/test/unit/index.test.ts.hbs +40 -0
- package/templates/hook-archetype/standard/tsconfig.json.hbs +15 -0
- package/templates/hook-archetype/standard/views/.gitkeep +1 -0
- package/testing.d.ts +1 -0
- package/testing.js +3 -0
|
@@ -0,0 +1,104 @@
|
|
|
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.createHookCompilerOptions = createHookCompilerOptions;
|
|
7
|
+
exports.createHookTsConfig = createHookTsConfig;
|
|
8
|
+
exports.cleanupHookTsConfig = cleanupHookTsConfig;
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const module_1 = require("module");
|
|
12
|
+
function toPosixPath(value) {
|
|
13
|
+
return value.split(path_1.default.sep).join('/');
|
|
14
|
+
}
|
|
15
|
+
function getPackageRequire(packageName) {
|
|
16
|
+
const packageJsonPath = packageName === '@researchdatabox/redbox-dev-tools'
|
|
17
|
+
? path_1.default.resolve(__dirname, '..', '..', 'package.json')
|
|
18
|
+
: require.resolve(`${packageName}/package.json`);
|
|
19
|
+
return (0, module_1.createRequire)(packageJsonPath);
|
|
20
|
+
}
|
|
21
|
+
function resolvePackageDir(resolver, request) {
|
|
22
|
+
try {
|
|
23
|
+
return path_1.default.dirname(resolver.resolve(`${request}/package.json`));
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function collectPathEntries(projectDir, entries) {
|
|
30
|
+
return entries
|
|
31
|
+
.filter((entry) => Boolean(entry))
|
|
32
|
+
.map(entry => toPosixPath(path_1.default.relative(projectDir, entry)))
|
|
33
|
+
.filter((entry, index, all) => entry.length > 0 && all.indexOf(entry) === index);
|
|
34
|
+
}
|
|
35
|
+
function getHookCompilerOptions(projectDir, projectTsconfig) {
|
|
36
|
+
const projectRequire = (0, module_1.createRequire)(projectTsconfig);
|
|
37
|
+
const redboxCoreRequire = getPackageRequire('@researchdatabox/redbox-core');
|
|
38
|
+
const redboxDevToolsRequire = getPackageRequire('@researchdatabox/redbox-dev-tools');
|
|
39
|
+
const redboxDevToolsDir = path_1.default.resolve(__dirname, '..', '..');
|
|
40
|
+
const localNodeTypes = path_1.default.join(projectDir, 'node_modules', '@types');
|
|
41
|
+
const devToolsNodeTypes = path_1.default.join(redboxDevToolsDir, 'node_modules', '@types');
|
|
42
|
+
const sailsNgCommonDirs = [
|
|
43
|
+
resolvePackageDir(redboxCoreRequire, '@researchdatabox/sails-ng-common'),
|
|
44
|
+
resolvePackageDir(projectRequire, '@researchdatabox/sails-ng-common'),
|
|
45
|
+
resolvePackageDir(redboxDevToolsRequire, '@researchdatabox/sails-ng-common'),
|
|
46
|
+
];
|
|
47
|
+
const axiosDirs = [
|
|
48
|
+
resolvePackageDir(redboxCoreRequire, 'axios'),
|
|
49
|
+
resolvePackageDir(projectRequire, 'axios'),
|
|
50
|
+
resolvePackageDir(redboxDevToolsRequire, 'axios'),
|
|
51
|
+
];
|
|
52
|
+
const rxjsDirs = [
|
|
53
|
+
resolvePackageDir(redboxCoreRequire, 'rxjs'),
|
|
54
|
+
resolvePackageDir(projectRequire, 'rxjs'),
|
|
55
|
+
resolvePackageDir(redboxDevToolsRequire, 'rxjs'),
|
|
56
|
+
];
|
|
57
|
+
const lodashDirs = [
|
|
58
|
+
resolvePackageDir(redboxCoreRequire, 'lodash'),
|
|
59
|
+
resolvePackageDir(projectRequire, 'lodash'),
|
|
60
|
+
resolvePackageDir(redboxDevToolsRequire, 'lodash'),
|
|
61
|
+
];
|
|
62
|
+
return {
|
|
63
|
+
baseUrl: '.',
|
|
64
|
+
paths: {
|
|
65
|
+
'@researchdatabox/sails-ng-common': collectPathEntries(projectDir, sailsNgCommonDirs),
|
|
66
|
+
axios: collectPathEntries(projectDir, axiosDirs),
|
|
67
|
+
rxjs: collectPathEntries(projectDir, rxjsDirs),
|
|
68
|
+
'rxjs/*': collectPathEntries(projectDir, rxjsDirs.map(entry => entry ? path_1.default.join(entry, '*') : null)),
|
|
69
|
+
lodash: collectPathEntries(projectDir, lodashDirs),
|
|
70
|
+
},
|
|
71
|
+
typeRoots: [
|
|
72
|
+
fs_1.default.existsSync(localNodeTypes) ? toPosixPath(path_1.default.relative(projectDir, localNodeTypes)) : null,
|
|
73
|
+
fs_1.default.existsSync(devToolsNodeTypes) ? toPosixPath(path_1.default.relative(projectDir, devToolsNodeTypes)) : null,
|
|
74
|
+
].filter((entry) => Boolean(entry)),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function createHookCompilerOptions(projectPath) {
|
|
78
|
+
const projectDir = process.cwd();
|
|
79
|
+
const projectTsconfig = path_1.default.resolve(projectDir, projectPath);
|
|
80
|
+
return getHookCompilerOptions(projectDir, projectTsconfig);
|
|
81
|
+
}
|
|
82
|
+
function createHookTsConfig(projectPath) {
|
|
83
|
+
const projectDir = process.cwd();
|
|
84
|
+
const projectTsconfig = path_1.default.resolve(projectDir, projectPath);
|
|
85
|
+
const compilerOptions = getHookCompilerOptions(projectDir, projectTsconfig);
|
|
86
|
+
const tempRootDir = path_1.default.join(projectDir, '.tmp', 'redbox-dev-tools');
|
|
87
|
+
fs_1.default.mkdirSync(tempRootDir, { recursive: true });
|
|
88
|
+
const tempDir = fs_1.default.mkdtempSync(path_1.default.join(tempRootDir, 'tsconfig-'));
|
|
89
|
+
const tempTsconfigPath = path_1.default.join(tempDir, 'tsconfig.json');
|
|
90
|
+
const tempConfig = {
|
|
91
|
+
extends: toPosixPath(path_1.default.relative(tempDir, projectTsconfig)),
|
|
92
|
+
compilerOptions: {
|
|
93
|
+
baseUrl: toPosixPath(path_1.default.relative(tempDir, projectDir)) || '.',
|
|
94
|
+
paths: compilerOptions.paths,
|
|
95
|
+
typeRoots: compilerOptions.typeRoots.map(entry => toPosixPath(path_1.default.relative(tempDir, path_1.default.resolve(projectDir, entry)))),
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
fs_1.default.writeFileSync(tempTsconfigPath, JSON.stringify(tempConfig, null, 2) + '\n');
|
|
99
|
+
return tempTsconfigPath;
|
|
100
|
+
}
|
|
101
|
+
function cleanupHookTsConfig(tempTsconfigPath) {
|
|
102
|
+
const tempDir = path_1.default.dirname(tempTsconfigPath);
|
|
103
|
+
fs_1.default.rmSync(tempDir, { recursive: true, force: true });
|
|
104
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
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
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.resolvePaths = resolvePaths;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
function resolvePaths(options) {
|
|
40
|
+
if (!options.root) {
|
|
41
|
+
throw new Error('The --root option is required for this command.');
|
|
42
|
+
}
|
|
43
|
+
const root = path.resolve(options.root);
|
|
44
|
+
if (!fs.existsSync(root)) {
|
|
45
|
+
throw new Error(`The provided root directory does not exist: ${root}`);
|
|
46
|
+
}
|
|
47
|
+
const coreTypes = options.coreTypesRoot
|
|
48
|
+
? path.resolve(options.coreTypesRoot)
|
|
49
|
+
: path.join(root, 'packages', 'redbox-core');
|
|
50
|
+
const angular = options.angularRoot ? path.resolve(options.angularRoot) : path.join(root, 'angular');
|
|
51
|
+
// Basic validation
|
|
52
|
+
if (!fs.existsSync(path.join(coreTypes, 'package.json'))) {
|
|
53
|
+
console.warn(`Warning: Could not find redbox-core at ${coreTypes}`);
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
root,
|
|
57
|
+
coreTypes,
|
|
58
|
+
angular,
|
|
59
|
+
};
|
|
60
|
+
}
|
package/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@researchdatabox/redbox-dev-tools",
|
|
3
|
+
"version": "0.0.1-beta.8936",
|
|
4
|
+
"description": "ReDBox customisation dev tools - shared configuration, generators, and migration tooling",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"redbox-dev-tools": "./bin/cli.js",
|
|
9
|
+
"redbox-hook-mocha": "./bin/run-hook-mocha.js",
|
|
10
|
+
"redbox-hook-tsc": "./bin/run-hook-tsc.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"bin/",
|
|
14
|
+
"dist/",
|
|
15
|
+
"config/",
|
|
16
|
+
"templates/",
|
|
17
|
+
"skills/",
|
|
18
|
+
"index.js",
|
|
19
|
+
"runtime-resolver.js",
|
|
20
|
+
"runtime-resolver.d.ts",
|
|
21
|
+
"testing.js",
|
|
22
|
+
"testing.d.ts",
|
|
23
|
+
"README.md"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc",
|
|
27
|
+
"test": "TS_NODE_PROJECT=test/tsconfig.json node -r ts-node/register ./node_modules/mocha/bin/_mocha --config .mocharc.js --exit test/**/*.test.ts"
|
|
28
|
+
},
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "git+https://github.com/redbox-mint/redbox-portal.git#v4.5.1"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"Kit",
|
|
35
|
+
"Dev",
|
|
36
|
+
"Hook",
|
|
37
|
+
"ReDBox",
|
|
38
|
+
"TypeScript"
|
|
39
|
+
],
|
|
40
|
+
"author": "Alejandro Bulgaris",
|
|
41
|
+
"license": "ISC",
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/redbox-mint/redbox-portal/issues"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://github.com/redbox-mint/redbox-portal/tree/v4.5.1#readme",
|
|
46
|
+
"dependencies": {
|
|
47
|
+
"@researchdatabox/redbox-core": "0.0.1-beta.8936",
|
|
48
|
+
"@researchdatabox/sails-ng-common": "0.0.1-beta.8936",
|
|
49
|
+
"@tsconfig/node24": "24.0.1",
|
|
50
|
+
"@types/chai": "5.2.3",
|
|
51
|
+
"@types/lodash": "4.17.24",
|
|
52
|
+
"@types/mocha": "10.0.10",
|
|
53
|
+
"@types/node": "24.10.0",
|
|
54
|
+
"axios": "1.15.0",
|
|
55
|
+
"chai": "6.2.2",
|
|
56
|
+
"commander": "14.0.3",
|
|
57
|
+
"handlebars": "4.7.9",
|
|
58
|
+
"lodash": "4.18.0",
|
|
59
|
+
"mocha": "11.7.4",
|
|
60
|
+
"rxjs": "7.8.1",
|
|
61
|
+
"ts-node": "10.9.2",
|
|
62
|
+
"ts-morph": "21.0.1",
|
|
63
|
+
"typescript": "5.8.3",
|
|
64
|
+
"zod": "3.25.28"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@types/sinon": "17.0.3",
|
|
68
|
+
"sinon": "17.0.1"
|
|
69
|
+
},
|
|
70
|
+
"peerDependenciesMeta": {
|
|
71
|
+
"@researchdatabox/redbox-core": {
|
|
72
|
+
"optional": false
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"overrides": {
|
|
76
|
+
"mocha": {
|
|
77
|
+
"serialize-javascript": "7.0.5"
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"publishConfig": {
|
|
81
|
+
"access": "public",
|
|
82
|
+
"registry": "https://registry.npmjs.org/",
|
|
83
|
+
"provenance": false
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './dist/runtime-resolver';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "Redbox Angular Apps"
|
|
3
|
+
description: "ReDBox uses embedded Angular applications within EJS views instead of a single SPA. Each feature is often its own Angular project."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill: Redbox Angular Apps
|
|
7
|
+
|
|
8
|
+
## Context
|
|
9
|
+
ReDBox uses embedded Angular applications within EJS views instead of a single SPA. Each feature is often its own Angular project.
|
|
10
|
+
|
|
11
|
+
## Locations
|
|
12
|
+
- Angular projects: `angular/projects/researchdatabox/<app-name>/`
|
|
13
|
+
- Output assets: `assets/angular/<app-name>/browser/`
|
|
14
|
+
- EJS views: `views/default/default/admin/<app-name>.ejs`
|
|
15
|
+
|
|
16
|
+
## Generating Angular Apps
|
|
17
|
+
Use the `redbox-dev-tools` CLI generator `generate_angular_app`:
|
|
18
|
+
- `name`: App name as an argument (lowercase).
|
|
19
|
+
- `--ejs-view <view>`: EJS view name.
|
|
20
|
+
- `--auth <roles>`: Roles for page access.
|
|
21
|
+
|
|
22
|
+
## Patterns
|
|
23
|
+
- Apps are scaffolded using `@angular-devkit/build-angular:application`.
|
|
24
|
+
- EJS views include the Angular component tag and the hashed JS/CSS bundles.
|
|
25
|
+
- Use `CacheService.getNgAppFileHash(appName, type, prefix)` for hashed asset names.
|
|
26
|
+
- Apps are usually served via `RenderViewController.render` with the view specified in `locals`.
|
|
27
|
+
|
|
28
|
+
## angular.json
|
|
29
|
+
New projects must be added to `angular.json` with appropriate `outputPath` and `baseHref`.
|
|
30
|
+
Example `outputPath`: `../assets/angular/<name>`
|
|
31
|
+
|
|
32
|
+
## Testing
|
|
33
|
+
To run tests for a specific Angular app:
|
|
34
|
+
- `ng test <app-name>`
|
|
35
|
+
- `npm test -- <app-name>`
|
|
36
|
+
|
|
37
|
+
### Root Execution
|
|
38
|
+
If running inside a container as root (e.g. Docker), you must use the `--browsers=ChromeHeadlessNoSandbox` flag:
|
|
39
|
+
`ng test --browsers=ChromeHeadlessNoSandbox <app-name>`
|
|
40
|
+
|
|
41
|
+
### Convenience Script
|
|
42
|
+
A convenience script is available at `support/unit-testing/angular/testDevAngular.sh` which handles the browser flags logic automatically.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "Redbox Angular Services"
|
|
3
|
+
description: "Angular services in ReDBox typically extend `HttpClientService` to handle base URLs, configuration, and CSRF protection."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill: Redbox Angular Services
|
|
7
|
+
|
|
8
|
+
## Context
|
|
9
|
+
Angular services in ReDBox typically extend `HttpClientService` to handle base URLs, configuration, and CSRF protection.
|
|
10
|
+
|
|
11
|
+
## Location
|
|
12
|
+
- Within an Angular project: `angular/projects/researchdatabox/<app-name>/src/app/`
|
|
13
|
+
|
|
14
|
+
## Patterns
|
|
15
|
+
- Extend `HttpClientService` from `@researchdatabox/portal-ng-common`.
|
|
16
|
+
- Inject `HttpClient`, `APP_BASE_HREF`, `UtilityService`, and `ConfigService`.
|
|
17
|
+
- Override `waitForInit()` and call `this.enableCsrfHeader()`.
|
|
18
|
+
- Use `this.brandingAndPortalUrl` for building API URLs.
|
|
19
|
+
- Use `this.httpContext` in request options to include the CSRF token.
|
|
20
|
+
|
|
21
|
+
## Generating Angular Services
|
|
22
|
+
Use the `redbox-dev-tools` CLI generator `generate_angular_service`:
|
|
23
|
+
- `name`: Service name as an argument.
|
|
24
|
+
- `--app <app>`: Target Angular app name.
|
|
25
|
+
- `--methods <methods>`: Comma-separated list of methods to generate (e.g. `get,save`).
|
|
26
|
+
|
|
27
|
+
## CSRF Handling
|
|
28
|
+
- `this.enableCsrfHeader()` sets the `RB_HTTP_INTERCEPTOR_AUTH_CSRF` context variable.
|
|
29
|
+
- For `FormData` uploads, you may need `RB_HTTP_INTERCEPTOR_SKIP_JSON_CONTENT_TYPE`.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: 'Redbox Controllers'
|
|
3
|
+
description: 'ReDBox controllers live in `@researchdatabox/redbox-core` and are surfaced to Sails.js through generated shims.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill: Redbox Controllers
|
|
7
|
+
|
|
8
|
+
## Context
|
|
9
|
+
|
|
10
|
+
ReDBox controllers live in `@researchdatabox/redbox-core` and are surfaced to Sails.js through generated shims.
|
|
11
|
+
|
|
12
|
+
## Locations
|
|
13
|
+
|
|
14
|
+
- API controllers: `packages/redbox-core/src/controllers/`
|
|
15
|
+
- Webservice controllers: `packages/redbox-core/src/controllers/webservice/`
|
|
16
|
+
|
|
17
|
+
## Patterns
|
|
18
|
+
|
|
19
|
+
- Extend `Controllers.Core.Controller`.
|
|
20
|
+
- Implement `init()` for sails-dependent setup (avoid using `sails` in constructors).
|
|
21
|
+
- Use `_exportedMethods` to define which methods are exposed.
|
|
22
|
+
- Actions are usually `async index(req, res)`.
|
|
23
|
+
- **Response Handling:** Use `this.sendResp(data, req, res)` instead of direct `res.json()` or `res.send()`. This ensures consistent response formatting.
|
|
24
|
+
|
|
25
|
+
## Type Safety Guidance
|
|
26
|
+
|
|
27
|
+
- Do not use `(object as any)`, `as any`, or other deliberate `any` casts to bypass TypeScript compilation errors. Fix the types, declare appropriate interfaces, or request assistance from the team.
|
|
28
|
+
|
|
29
|
+
## Generating Controllers
|
|
30
|
+
|
|
31
|
+
Use the `redbox-dev-tools` CLI generator `generate controller`:
|
|
32
|
+
|
|
33
|
+
- `name`: Controller name (e.g., `MyRecord`) as an argument.
|
|
34
|
+
- `--actions <list>`: Comma-separated actions (e.g., `index,get,save`).
|
|
35
|
+
- `--webservice`: If it's a webservice controller.
|
|
36
|
+
- `--routes <routes>`: Action-to-route mappings: `action:verb:path[:role1:role2],...` (e.g., `list:get:/api/items:Admin:Researcher`).
|
|
37
|
+
- `--auth <roles>`: Default roles for auth rules (can be overridden per-route).
|
|
38
|
+
|
|
39
|
+
## Adding Methods
|
|
40
|
+
|
|
41
|
+
Use `redbox-dev-tools generate method` to add actions to an existing controller:
|
|
42
|
+
|
|
43
|
+
- `--file <path>`: Path to the controller file.
|
|
44
|
+
- `--method <name>`: Method name.
|
|
45
|
+
- `--route <route>`: Route path (e.g., `/api/new-path`).
|
|
46
|
+
- `--http <verb>`: HTTP verb (GET, POST, etc.).
|
|
47
|
+
- `--auth <roles>`: Auth roles.
|
|
48
|
+
|
|
49
|
+
## Index Updates
|
|
50
|
+
|
|
51
|
+
When adding a controller, you must update `packages/redbox-core/src/controllers/index.ts`:
|
|
52
|
+
|
|
53
|
+
- Import the controller module.
|
|
54
|
+
- Add to `ControllerExports` (or `WebserviceControllerExports`) with a lazy getter.
|
|
55
|
+
- Add to `ControllerNames` (or `WebserviceControllerNames`) array.
|
|
56
|
+
|
|
57
|
+
## Route Configuration
|
|
58
|
+
|
|
59
|
+
Routes are defined in `packages/redbox-core/src/config/routes.config.ts`.
|
|
60
|
+
Pattern: `'get /api/my-path': { controller: 'MyController', action: 'index' }`
|
|
61
|
+
|
|
62
|
+
## Auth Rules
|
|
63
|
+
|
|
64
|
+
Auth rules are defined in `packages/redbox-core/src/config/auth.config.ts`.
|
|
65
|
+
Pattern: `{ path: '/api/my-path', role: 'admin', can_read: true }`
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: redbox-feature-design-planner
|
|
3
|
+
description: Create detailed feature designs, implementation plans, and task lists for ReDBox/Redbox features that use Waterline models, services, webservice (REST) controllers, ajax controllers, embedded Angular apps, views, and navigation config. Use when asked to design/plan a feature or produce a task list for this stack, especially when explicit sections, non-SPA Angular patterns, and interleaved tests are required.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Redbox Feature Design Planner
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Produce a detailed design, implementation plan, and task list for ReDBox features, organized by the required architecture sections and validated for internal consistency.
|
|
11
|
+
|
|
12
|
+
## Required Nuances (Must Apply)
|
|
13
|
+
|
|
14
|
+
- **Angular apps are embedded, not SPAs.** Do not design Angular routing. Pages are routed by Sails + EJS views, and Angular apps mount inside those views.
|
|
15
|
+
- **Controllers/services/models live in `@researchdatabox/redbox-core` and are surfaced via shims.** Respect loader/shim behavior and registration conventions.
|
|
16
|
+
- **Controllers use `init()` + `_exportedMethods` and respond via `sendResp`.** Avoid `sails` usage in constructors.
|
|
17
|
+
- **Auth and routes are explicit config.** Route entries live in `packages/redbox-core/src/config/routes.config.ts` and auth rules in `packages/redbox-core/src/config/auth.config.ts`.
|
|
18
|
+
- **Hook overrides are first-class.** If the feature is delivered via a hook, ensure `package.json` `sails` capabilities match exports and that overrides use the same names as core components.
|
|
19
|
+
- **Use Hook Kit CLI generators when possible.** Prefer `redbox-dev-tools` generators for scaffolding controllers, services, models, Angular apps/services, and form fields.
|
|
20
|
+
|
|
21
|
+
## Workflow
|
|
22
|
+
|
|
23
|
+
1. Gather scope and assumptions
|
|
24
|
+
- Extract: feature goal, primary users, key workflows, data entities, and required UI surfaces.
|
|
25
|
+
- Ask up to 3 clarifying questions only if required to avoid blocking.
|
|
26
|
+
- If information is missing, state explicit assumptions before the design.
|
|
27
|
+
|
|
28
|
+
2. Consult authoritative references (lightweight)
|
|
29
|
+
- Prefer wiki docs under `support/wiki/` (Architecture, Controllers, Services, Loader, Hook Kit, Testing, Hook customization).
|
|
30
|
+
- Use relevant skills: Redbox Services, Redbox Controllers, Redbox Angular Apps, Redbox Angular Services, Redbox Hook Development, Redbox Testing.
|
|
31
|
+
|
|
32
|
+
3. Produce the design in required sections
|
|
33
|
+
- Use the exact section order in the Output Template below.
|
|
34
|
+
- For each section, specify: purpose, new/changed files, new/changed APIs, validation rules, permissions, and edge cases.
|
|
35
|
+
- Keep names consistent across sections (models, services, controllers, Angular modules, routes).
|
|
36
|
+
|
|
37
|
+
4. Run consistency analysis
|
|
38
|
+
- Validate the design end-to-end: models -> services -> controllers -> UI -> navigation.
|
|
39
|
+
- Call out mismatches, missing artifacts, or unclear ownership.
|
|
40
|
+
- List open questions and risks separately from assumptions.
|
|
41
|
+
|
|
42
|
+
5. Produce the implementation plan
|
|
43
|
+
- Provide ordered steps with file-level granularity and rationale.
|
|
44
|
+
- Reference relevant skills explicitly for each step.
|
|
45
|
+
|
|
46
|
+
6. Produce the task list with tests interleaved
|
|
47
|
+
- Match the same section order as the design.
|
|
48
|
+
- Interleave unit tests after each task, not at the end.
|
|
49
|
+
- Add integration test gates exactly at the required points.
|
|
50
|
+
- Explicitly mention which skills to use for each task.
|
|
51
|
+
- Identify missing skills required to complete tasks.
|
|
52
|
+
|
|
53
|
+
## Output Template
|
|
54
|
+
|
|
55
|
+
Use this structure and headings verbatim. Keep content concise but explicit.
|
|
56
|
+
|
|
57
|
+
# Design
|
|
58
|
+
|
|
59
|
+
## 1. Data Model (Waterline Models)
|
|
60
|
+
|
|
61
|
+
- Purpose and scope
|
|
62
|
+
- New/changed models and attributes
|
|
63
|
+
- Relationships and indexes
|
|
64
|
+
- Validation, lifecycle hooks, and defaults
|
|
65
|
+
- Access control considerations
|
|
66
|
+
- File locations and naming (core-types vs hook, and shim implications)
|
|
67
|
+
- Hook delivery requirements (capabilities + `registerRedboxModels()` if applicable)
|
|
68
|
+
|
|
69
|
+
## 2. Services Layer (Business Logic)
|
|
70
|
+
|
|
71
|
+
- Service responsibilities
|
|
72
|
+
- Public methods, inputs/outputs, and errors
|
|
73
|
+
- Transaction boundaries and side effects
|
|
74
|
+
- Dependencies on models, configs, or external services
|
|
75
|
+
- File locations and naming
|
|
76
|
+
- Service conventions (extend `Services.Core.Service`, `_exportedMethods`, `bootstrap()`, RxJS, model globals)
|
|
77
|
+
- Export/update requirements (ServiceExports index and hook overrides)
|
|
78
|
+
|
|
79
|
+
## 3. Webservice Controllers (REST API)
|
|
80
|
+
|
|
81
|
+
- Endpoint list (method + path)
|
|
82
|
+
- Request/response shapes and status codes
|
|
83
|
+
- Authn/authz and policy usage
|
|
84
|
+
- Error handling and validation (use `sendResp`)
|
|
85
|
+
- File locations and naming
|
|
86
|
+
- Controller conventions (extend `Controllers.Core.Controller`, `init()`, `_exportedMethods`)
|
|
87
|
+
- Export/update requirements (ControllerExports index, routes, auth config)
|
|
88
|
+
|
|
89
|
+
## 4. Ajax Controllers (Controllers)
|
|
90
|
+
|
|
91
|
+
- Endpoint list (method + path or action)
|
|
92
|
+
- Request/response shapes
|
|
93
|
+
- Authn/authz and policy usage
|
|
94
|
+
- Error handling and validation (use `sendResp`)
|
|
95
|
+
- File locations and naming
|
|
96
|
+
- Controller conventions (extend `Controllers.Core.Controller`, `init()`, `_exportedMethods`)
|
|
97
|
+
- Export/update requirements (ControllerExports index, routes, auth config)
|
|
98
|
+
|
|
99
|
+
## 5. Angular App(s)
|
|
100
|
+
|
|
101
|
+
- Apps/modules to add or modify (embedded apps only)
|
|
102
|
+
- Routes: **Do not use Angular Router**; specify Sails/EJS view routing instead
|
|
103
|
+
- Components and services
|
|
104
|
+
- Data flow to/from APIs
|
|
105
|
+
- State management and error handling
|
|
106
|
+
- File locations and naming (Angular workspace + EJS view + assets output)
|
|
107
|
+
- EJS view wiring (component tag + hashed asset includes using `CacheService.getNgAppFileHash`)
|
|
108
|
+
- Render path (typically `RenderViewController.render` with `locals.view`)
|
|
109
|
+
|
|
110
|
+
## 6. Additional Views
|
|
111
|
+
|
|
112
|
+
- View templates to add/modify
|
|
113
|
+
- Server-side data needed to render
|
|
114
|
+
- Where view is wired in (e.g., RenderViewController.render)
|
|
115
|
+
- Hook asset/view copy behavior if applicable
|
|
116
|
+
|
|
117
|
+
## 7. Navigation Configuration
|
|
118
|
+
|
|
119
|
+
- Menu/route entries to add/modify
|
|
120
|
+
- Role/permission gating
|
|
121
|
+
- File locations and naming
|
|
122
|
+
|
|
123
|
+
# Consistency Analysis
|
|
124
|
+
|
|
125
|
+
- Cross-checks across all layers
|
|
126
|
+
- Missing pieces or conflicts
|
|
127
|
+
- Assumptions
|
|
128
|
+
- Open questions
|
|
129
|
+
- Risks
|
|
130
|
+
|
|
131
|
+
# Implementation Plan
|
|
132
|
+
|
|
133
|
+
- Step-by-step plan with file-level detail and skill references
|
|
134
|
+
|
|
135
|
+
# Task List (With Tests and Skill Usage)
|
|
136
|
+
|
|
137
|
+
- Sectioned tasks following the same order as the design
|
|
138
|
+
- Each task includes a matching unit test task
|
|
139
|
+
- Before any integration test run task, add a code review task using the redbox-feature-implementation-review skill with instructions:
|
|
140
|
+
- If issues are found: write the result to issues.json in the project root
|
|
141
|
+
- If issues are found: add two tasks immediately after the current task:
|
|
142
|
+
- Fix all issues listed in issues.json and delete issues.json when done
|
|
143
|
+
- Re-run the code review using redbox-feature-implementation-review
|
|
144
|
+
- Integration test gates:
|
|
145
|
+
- After Data Model + Services: create Mocha integration tests and run them; do not continue until passing
|
|
146
|
+
- After Controllers: create Bruno tests and run them; do not continue until passing
|
|
147
|
+
- Final: run both integration suites again
|
|
148
|
+
- Each task explicitly names required skills
|
|
149
|
+
- End with a "Skill Gaps" subsection if any skills are missing
|
|
150
|
+
|
|
151
|
+
## Skill Guidance
|
|
152
|
+
|
|
153
|
+
- Reference existing skills by name when writing tasks.
|
|
154
|
+
- Prefer these skills when relevant: Redbox Services, Redbox Controllers, Redbox Angular Apps, Redbox Angular Services, Redbox Hook Development, Redbox Form Config, Redbox Testing, Web Interface Verification.
|
|
155
|
+
- Use Hook Kit CLI generators when they match the task (controllers, services, models, Angular apps/services, form fields).
|
|
156
|
+
- If a task does not map cleanly to an existing skill, call it out under "Skill Gaps" and suggest a new skill name and scope.
|
|
157
|
+
|
|
158
|
+
## Repo Context Reminders
|
|
159
|
+
|
|
160
|
+
- Prefer wiki documentation under `support/wiki/` when referencing ReDBox architecture or conventions.
|
|
161
|
+
- Key docs: `Controllers-Architecture`, `Services-Architecture`, `Redbox-Loader`, `redbox-dev-tools`, `ReDBox-Automated-Tests`, `Using-a-Sails-Hook-to-customise-ReDBox`.
|
|
162
|
+
- Use the Coding Standards wiki for naming conventions and TypeScript rules.
|
|
163
|
+
- Use Redbox Testing skill guidance for Mocha and Bruno testing workflows.
|
|
164
|
+
|
|
165
|
+
## Notes on Specificity
|
|
166
|
+
|
|
167
|
+
- Be explicit enough that a smaller model can execute the plan without inference.
|
|
168
|
+
- Include concrete file path examples when possible.
|
|
169
|
+
- Avoid vague statements like "update the service"; name the service, method, and expected behavior.
|