@researchdatabox/redbox-dev-tools 0.0.1 → 5.0.0-RC2
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 +259 -14
- 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 +168 -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 +495 -0
- package/dist/commands/form-config.d.ts +6 -0
- package/dist/commands/form-config.js +401 -0
- package/dist/commands/sync-translation.d.ts +23 -0
- package/dist/commands/sync-translation.js +348 -0
- package/dist/completion/index.d.ts +1 -0
- package/dist/completion/index.js +218 -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/migration.d.ts +15 -0
- package/dist/generators/migration.js +100 -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 +187 -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 +76 -19
- 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 +5 -0
- package/templates/hook-archetype/standard/.npmignore.hbs +4 -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 +51 -0
- package/templates/hook-archetype/standard/Dockerfile.hbs +29 -0
- package/templates/hook-archetype/standard/README.md.hbs +57 -0
- package/templates/hook-archetype/standard/assets/default/.gitkeep +1 -0
- package/templates/hook-archetype/standard/assets/fonts/.gitkeep +1 -0
- package/templates/hook-archetype/standard/assets/images/.gitkeep +1 -0
- package/templates/hook-archetype/standard/assets/styles/.gitkeep +1 -0
- package/templates/hook-archetype/standard/language-defaults/.gitkeep +1 -0
- package/templates/hook-archetype/standard/language-defaults/README.md.hbs +10 -0
- package/templates/hook-archetype/standard/language-defaults/en/translation.json.hbs +3 -0
- package/templates/hook-archetype/standard/language-defaults/meta.json.hbs +6 -0
- package/templates/hook-archetype/standard/package.json.hbs +44 -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/src/migrations/index.ts.hbs +19 -0
- package/templates/hook-archetype/standard/support/bootstrap-data/.gitkeep +1 -0
- package/templates/hook-archetype/standard/support/bootstrap-data/namedqueries/.gitkeep +1 -0
- package/templates/hook-archetype/standard/support/bootstrap-data/records/.gitkeep +1 -0
- package/templates/hook-archetype/standard/support/bootstrap-data/reports/.gitkeep +1 -0
- package/templates/hook-archetype/standard/support/bootstrap-data/vocabularies/.gitkeep +1 -0
- package/templates/hook-archetype/standard/support/development/core-mount.env.hbs +3 -0
- package/templates/hook-archetype/standard/support/development/docker-compose.core-mount.yml.hbs +37 -0
- package/templates/hook-archetype/standard/support/development/docker-compose.yml.hbs +108 -0
- package/templates/hook-archetype/standard/support/development/prepare-core-mount.sh.hbs +61 -0
- package/templates/hook-archetype/standard/support/integration-testing/docker-compose.mocha.yml.hbs +118 -0
- package/templates/hook-archetype/standard/support/integration-testing/run-mocha-hook.sh.hbs +14 -0
- package/templates/hook-archetype/standard/support/integration-testing/run-mocha-redbox.sh.hbs +100 -0
- package/templates/hook-archetype/standard/support/prepare-minio.sh.hbs +74 -0
- package/templates/hook-archetype/standard/test/integration/hook-registration.test.ts.hbs +15 -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 +46 -0
- package/templates/hook-archetype/standard/tsconfig.json.hbs +15 -0
- package/templates/hook-archetype/standard/views/.gitkeep +1 -0
- package/templates/hook-archetype/standard/views/default/.gitkeep +1 -0
- package/testing.d.ts +1 -0
- package/testing.js +3 -0
- package/.travis.yml +0 -23
- package/commands/initProject.js +0 -129
- package/redbox-dev-tools +0 -70
- package/yarn.lock +0 -1061
|
@@ -0,0 +1,401 @@
|
|
|
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.registerMigrateFormConfigCommand = registerMigrateFormConfigCommand;
|
|
40
|
+
exports.registerMigrateDataClassificationCommand = registerMigrateDataClassificationCommand;
|
|
41
|
+
exports.registerClientFormConfigCommand = registerClientFormConfigCommand;
|
|
42
|
+
exports.registerQuestionTreeDiagramCommand = registerQuestionTreeDiagramCommand;
|
|
43
|
+
exports.registerMigrateFigshareConfigCommand = registerMigrateFigshareConfigCommand;
|
|
44
|
+
const fs_1 = __importDefault(require("fs"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const redbox_core_1 = require("@researchdatabox/redbox-core");
|
|
47
|
+
const migrationLogger = {
|
|
48
|
+
silly: (...args) => console.debug(...args),
|
|
49
|
+
verbose: (...args) => console.debug(...args),
|
|
50
|
+
trace: (...args) => console.debug(...args),
|
|
51
|
+
debug: (...args) => console.debug(...args),
|
|
52
|
+
log: (...args) => console.log(...args),
|
|
53
|
+
info: (...args) => console.info(...args),
|
|
54
|
+
warn: (...args) => console.warn(...args),
|
|
55
|
+
error: (...args) => console.error(...args),
|
|
56
|
+
crit: (...args) => console.error(...args),
|
|
57
|
+
fatal: (...args) => console.error(...args),
|
|
58
|
+
silent: () => undefined,
|
|
59
|
+
blank: () => undefined,
|
|
60
|
+
};
|
|
61
|
+
function registerMigrateFormConfigCommand(program) {
|
|
62
|
+
program
|
|
63
|
+
.command('migrate-form-config')
|
|
64
|
+
.description('Migrate a legacy v4 JS form config file to the v5 TS form framework format')
|
|
65
|
+
.requiredOption('-i, --input <path>', 'Path to the legacy v4 form config JS file')
|
|
66
|
+
.requiredOption('-o, --output <path>', 'Path to write the migrated v5 TypeScript config file')
|
|
67
|
+
.option('--format <name>', "The output format, either 'esm' or 'cjs'")
|
|
68
|
+
.action(async (options) => {
|
|
69
|
+
try {
|
|
70
|
+
const globalOptions = program.opts();
|
|
71
|
+
const inputPath = path.resolve(options.input);
|
|
72
|
+
const outputPath = path.resolve(options.output);
|
|
73
|
+
const outputFormat = options.format || "esm";
|
|
74
|
+
console.log(`\n🛠️ Migrating form config to ${outputFormat} format: ${inputPath} -> ${outputPath}\n`);
|
|
75
|
+
const migrateVisitor = new redbox_core_1.MigrationV4ToV5FormConfigVisitor(migrationLogger);
|
|
76
|
+
const migrated = await (0, redbox_core_1.migrateFormConfigFile)(migrateVisitor, inputPath, outputFormat);
|
|
77
|
+
if (globalOptions.dryRun) {
|
|
78
|
+
console.log('[dry-run] Migration completed; no file written.');
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
fs_1.default.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
82
|
+
fs_1.default.writeFileSync(outputPath, migrated.tsContent, 'utf8');
|
|
83
|
+
console.log(`✅ Wrote migrated form config: ${outputPath}`);
|
|
84
|
+
}
|
|
85
|
+
await (0, redbox_core_1.migrateFormConfigVerify)(migrated.migrated, migrationLogger);
|
|
86
|
+
console.log('\n✅ Done!\n');
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
console.error(`\n❌ Error: `, error);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function registerMigrateDataClassificationCommand(program) {
|
|
95
|
+
program
|
|
96
|
+
.command('migrate-data-classification')
|
|
97
|
+
.description('Migrate a legacy v4 JS data classification definition file to the v5 TS form framework format')
|
|
98
|
+
.requiredOption('-i, --input <path>', 'Path to the legacy v4 JS data classification definition file')
|
|
99
|
+
.requiredOption('-o, --output <path>', 'Path to write the migrated v5 TypeScript question tree config file')
|
|
100
|
+
.option('--format <name>', "The output format, either 'esm' or 'cjs'")
|
|
101
|
+
.action(async (options) => {
|
|
102
|
+
try {
|
|
103
|
+
const globalOptions = program.opts();
|
|
104
|
+
const inputPath = path.resolve(options.input);
|
|
105
|
+
const outputPath = path.resolve(options.output);
|
|
106
|
+
const outputFormat = options.format || 'esm';
|
|
107
|
+
console.log(`\n🛠️ Migrating data classification to question tree to ${outputFormat} format: ${inputPath} -> ${outputPath}\n`);
|
|
108
|
+
const migrateVisitor = new redbox_core_1.MigrationV4ToV5FormConfigVisitor(migrationLogger);
|
|
109
|
+
const migrated = (0, redbox_core_1.migrateDataClassification)(migrateVisitor, inputPath, outputFormat);
|
|
110
|
+
if (globalOptions.dryRun) {
|
|
111
|
+
console.log('[dry-run] Migration completed; no file written.');
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
fs_1.default.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
115
|
+
fs_1.default.writeFileSync(outputPath, migrated.tsContent, 'utf8');
|
|
116
|
+
console.log(`✅ Wrote migrated question tree config: ${outputPath}`);
|
|
117
|
+
}
|
|
118
|
+
await (0, redbox_core_1.migrateFormConfigVerify)(migrated.formConfig, migrationLogger);
|
|
119
|
+
console.log('\n✅ Done!\n');
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
console.error(`\n❌ Error: `, error);
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
function registerClientFormConfigCommand(program) {
|
|
128
|
+
program
|
|
129
|
+
.command('client-form-config')
|
|
130
|
+
.description('Process a form config to produce the client form config')
|
|
131
|
+
.requiredOption('-i, --input <path>', 'Path to read the server-side form config TypeScript file')
|
|
132
|
+
.requiredOption('-o, --output <path>', 'Path to write the client-side form config TypeScript file')
|
|
133
|
+
.option('--formMode <name>', "The form mode, either 'edit' or 'view'")
|
|
134
|
+
.option('--userRoles <name...>', "The user roles, zero or more of 'Admin', 'Librarians', 'Researcher', 'Guest'")
|
|
135
|
+
.option('-r, --record <path>', "Path to read the data record file")
|
|
136
|
+
.action(async (options) => {
|
|
137
|
+
try {
|
|
138
|
+
const globalOptions = program.opts();
|
|
139
|
+
const inputPath = path.resolve(options.input);
|
|
140
|
+
const outputPath = path.resolve(options.output);
|
|
141
|
+
const formMode = options.formMode ?? null;
|
|
142
|
+
const userRoles = options.userRoles ?? null;
|
|
143
|
+
const record = options.record ? require(path.resolve(options.record)) : null;
|
|
144
|
+
console.log(`\n🛠️ Building client form config from server form config: ${inputPath} -> ${outputPath}\n`);
|
|
145
|
+
const serverFormConfig = require(inputPath).default;
|
|
146
|
+
const clientFormConfig = await (0, redbox_core_1.createClientFormConfig)(serverFormConfig, migrationLogger, formMode, userRoles, undefined, record);
|
|
147
|
+
const tsContent = `import { FormConfigFrame } from '@researchdatabox/sails-ng-common';
|
|
148
|
+
const clientFormConfig: FormConfigFrame = ${JSON.stringify(clientFormConfig, null, 2)};
|
|
149
|
+
export default clientFormConfig;`;
|
|
150
|
+
if (globalOptions.dryRun) {
|
|
151
|
+
console.log('[dry-run] Client form config built from server form config; no file written.');
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
fs_1.default.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
155
|
+
fs_1.default.writeFileSync(outputPath, tsContent, 'utf8');
|
|
156
|
+
console.log(`✅ Wrote client form config: ${outputPath}`);
|
|
157
|
+
}
|
|
158
|
+
await (0, redbox_core_1.migrateFormConfigVerify)(clientFormConfig, migrationLogger);
|
|
159
|
+
console.log('\n✅ Done!\n');
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
console.error(`\n❌ Error: `, error);
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
function registerQuestionTreeDiagramCommand(program) {
|
|
168
|
+
program
|
|
169
|
+
.command('question-tree-diagram')
|
|
170
|
+
.description('Convert a question tree config to a mermaid diagram text file')
|
|
171
|
+
.requiredOption('-i, --input <path>', 'Path to read the question tree form config TypeScript file')
|
|
172
|
+
.requiredOption('-o, --output <path>', 'Path to write the diagram text file')
|
|
173
|
+
.action(async (options) => {
|
|
174
|
+
try {
|
|
175
|
+
const globalOptions = program.opts();
|
|
176
|
+
const inputPath = path.resolve(options.input);
|
|
177
|
+
const outputPath = path.resolve(options.output);
|
|
178
|
+
console.log(`\n🛠️ Creating diagram from form config: ${inputPath} -> ${outputPath}\n`);
|
|
179
|
+
const componentConfig = require(inputPath);
|
|
180
|
+
const diagram = await (0, redbox_core_1.createQuestionTreeDiagram)(componentConfig, migrationLogger);
|
|
181
|
+
if (globalOptions.dryRun) {
|
|
182
|
+
console.log('[dry-run] Built diagram from form config; no file written.');
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
fs_1.default.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
186
|
+
fs_1.default.writeFileSync(outputPath, diagram, 'utf8');
|
|
187
|
+
console.log(`✅ Wrote diagram text file: ${outputPath}`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
console.error(`\n❌ Error: `, error);
|
|
192
|
+
process.exit(1);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
function collectLegacyTemplates(value, pathPrefix = '') {
|
|
197
|
+
if (typeof value === 'string') {
|
|
198
|
+
return value.includes('<%') ? [pathPrefix] : [];
|
|
199
|
+
}
|
|
200
|
+
if (Array.isArray(value)) {
|
|
201
|
+
return value.flatMap((entry, index) => collectLegacyTemplates(entry, `${pathPrefix}[${index}]`));
|
|
202
|
+
}
|
|
203
|
+
if (value && typeof value === 'object') {
|
|
204
|
+
return Object.entries(value).flatMap(([key, entry]) => collectLegacyTemplates(entry, pathPrefix ? `${pathPrefix}.${key}` : key));
|
|
205
|
+
}
|
|
206
|
+
return [];
|
|
207
|
+
}
|
|
208
|
+
function loadLegacyModule(modulePath) {
|
|
209
|
+
const resolvedPath = path.resolve(modulePath);
|
|
210
|
+
const loaded = require(resolvedPath);
|
|
211
|
+
if (loaded == null || typeof loaded !== 'object') {
|
|
212
|
+
throw new Error(`Legacy config module '${resolvedPath}' did not export an object`);
|
|
213
|
+
}
|
|
214
|
+
return loaded;
|
|
215
|
+
}
|
|
216
|
+
function pickLegacyExport(moduleExports, exportName) {
|
|
217
|
+
const named = moduleExports[exportName];
|
|
218
|
+
if (named != null && typeof named === 'object') {
|
|
219
|
+
return named;
|
|
220
|
+
}
|
|
221
|
+
return moduleExports;
|
|
222
|
+
}
|
|
223
|
+
function toNumericStatusCodes(value) {
|
|
224
|
+
if (!Array.isArray(value)) {
|
|
225
|
+
return [408, 429, 500, 502, 503, 504];
|
|
226
|
+
}
|
|
227
|
+
return value
|
|
228
|
+
.map((entry) => Number(entry))
|
|
229
|
+
.filter((entry) => Number.isFinite(entry));
|
|
230
|
+
}
|
|
231
|
+
function createMigratedFigsharePublishingConfig(brand, figshareApi, figshareApiEnv = {}, figshareForMapping = {}) {
|
|
232
|
+
const overrideArtifacts = figshareApiEnv.overrideArtifacts ?? {};
|
|
233
|
+
const mapping = {
|
|
234
|
+
...(figshareApi.mapping ?? {}),
|
|
235
|
+
...(overrideArtifacts.mapping ?? {})
|
|
236
|
+
};
|
|
237
|
+
const resolvedBaseUrl = String(overrideArtifacts.baseURL ?? figshareApi.baseURL ?? '');
|
|
238
|
+
const resolvedFrontEndUrl = String(overrideArtifacts.frontEndURL ?? figshareApi.frontEndURL ?? '');
|
|
239
|
+
const resolvedToken = String(overrideArtifacts.APIToken ?? figshareApi.APIToken ?? '');
|
|
240
|
+
return {
|
|
241
|
+
enabled: Boolean(resolvedToken && resolvedBaseUrl && resolvedFrontEndUrl),
|
|
242
|
+
connection: {
|
|
243
|
+
baseUrl: resolvedBaseUrl,
|
|
244
|
+
frontEndUrl: resolvedFrontEndUrl,
|
|
245
|
+
token: resolvedToken,
|
|
246
|
+
timeoutMs: 30000,
|
|
247
|
+
operationTimeouts: {
|
|
248
|
+
metadataMs: 30000,
|
|
249
|
+
uploadInitMs: 30000,
|
|
250
|
+
uploadPartMs: 120000,
|
|
251
|
+
publishMs: 60000
|
|
252
|
+
},
|
|
253
|
+
retry: {
|
|
254
|
+
maxAttempts: Number(figshareApi.retry?.maxAttempts ?? 3),
|
|
255
|
+
baseDelayMs: Number(figshareApi.retry?.baseDelayMs ?? 500),
|
|
256
|
+
maxDelayMs: Number(figshareApi.retry?.maxDelayMs ?? 4000),
|
|
257
|
+
retryOnStatusCodes: toNumericStatusCodes(figshareApi.retry?.retryOnStatusCodes),
|
|
258
|
+
retryOnMethods: ['get', 'put', 'delete']
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
article: {
|
|
262
|
+
itemType: mapping.figshareItemType ?? 'dataset',
|
|
263
|
+
groupId: mapping.figshareItemGroupId,
|
|
264
|
+
publishMode: mapping.figshareNeedsPublishAfterFileUpload ? 'afterUploadsComplete' : 'immediate',
|
|
265
|
+
republishOnMetadataChange: true,
|
|
266
|
+
republishOnAssetChange: true
|
|
267
|
+
},
|
|
268
|
+
record: {
|
|
269
|
+
articleIdPath: mapping.recordFigArticleId ?? 'metadata.figshare_article_id',
|
|
270
|
+
dataLocationsPath: mapping.recordDataLocations ?? 'metadata.dataLocations',
|
|
271
|
+
statusPath: 'metadata.figshareStatus',
|
|
272
|
+
errorPath: 'metadata.figshareError',
|
|
273
|
+
syncStatePath: 'metadata.figshareSyncState',
|
|
274
|
+
allFilesUploadedPath: typeof mapping.recordAllFilesUploaded === 'string' ? mapping.recordAllFilesUploaded : ''
|
|
275
|
+
},
|
|
276
|
+
selection: {
|
|
277
|
+
attachmentMode: mapping.figshareOnlyPublishSelectedAttachmentFiles ? 'selectedOnly' : 'all',
|
|
278
|
+
urlMode: mapping.figshareOnlyPublishSelectedLocationURLs ? 'selectedOnly' : 'all',
|
|
279
|
+
selectedFlagPath: 'selected'
|
|
280
|
+
},
|
|
281
|
+
authors: {
|
|
282
|
+
uniqueBy: mapping.recordAuthorUniqueBy ?? 'email',
|
|
283
|
+
externalNameField: mapping.recordAuthorExternalName ?? 'text_full_name',
|
|
284
|
+
maxInlineAuthors: 50,
|
|
285
|
+
contributorPaths: ['metadata.contributor_ci', 'metadata.contributors'],
|
|
286
|
+
lookup: []
|
|
287
|
+
},
|
|
288
|
+
metadata: {
|
|
289
|
+
title: { kind: 'path', path: 'metadata.title' },
|
|
290
|
+
description: { kind: 'path', path: 'metadata.description' },
|
|
291
|
+
keywords: { kind: 'path', path: 'metadata.finalKeywords', defaultValue: [] },
|
|
292
|
+
funding: { kind: 'path', path: 'metadata.funder' },
|
|
293
|
+
license: { source: { kind: 'path', path: mapping.recordLicensePath ?? 'metadata.license' }, matchBy: 'urlContains', required: true },
|
|
294
|
+
categories: { source: { kind: 'path', path: mapping.recordCategoryPath ?? 'metadata.forCodes', defaultValue: [] } },
|
|
295
|
+
customFields: []
|
|
296
|
+
},
|
|
297
|
+
categories: {
|
|
298
|
+
mappingTable: ((figshareForMapping.FORMapping ?? []).map((entry) => ({
|
|
299
|
+
sourceCode: String(entry.redboxCode ?? entry.sourceCode ?? ''),
|
|
300
|
+
figshareCategoryId: Number(entry.figshareCategoryId ?? entry.figCode ?? 0)
|
|
301
|
+
}))).filter((entry) => entry.sourceCode !== ''),
|
|
302
|
+
allowUnmapped: false
|
|
303
|
+
},
|
|
304
|
+
assets: {
|
|
305
|
+
enableHostedFiles: true,
|
|
306
|
+
enableLinkFiles: true,
|
|
307
|
+
staging: {
|
|
308
|
+
cleanupPolicy: 'deleteAfterSuccess'
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
embargo: {
|
|
312
|
+
mode: 'recordDriven',
|
|
313
|
+
forceSync: Boolean(mapping.figshareForceEmbargoUpdateAlways),
|
|
314
|
+
accessRights: {
|
|
315
|
+
accessRights: { kind: 'path', path: 'metadata.accessRights' },
|
|
316
|
+
fullEmbargoUntil: { kind: 'path', path: 'metadata.embargoUntil' },
|
|
317
|
+
reason: { kind: 'path', path: 'metadata.embargoReason' }
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
queue: {
|
|
321
|
+
publishAfterUploadDelay: typeof mapping.schedulePublishAfterUploadJob === 'string' ? mapping.schedulePublishAfterUploadJob : 'in 2 minutes',
|
|
322
|
+
uploadedFilesCleanupDelay: typeof mapping.scheduleUploadedFilesCleanupJob === 'string' ? mapping.scheduleUploadedFilesCleanupJob : 'in 5 minutes'
|
|
323
|
+
},
|
|
324
|
+
workflow: {
|
|
325
|
+
transitionJob: {
|
|
326
|
+
enabled: String(mapping.figshareScheduledTransitionRecordWorkflowFromArticlePropertiesJob?.enabled ?? 'false') === 'true',
|
|
327
|
+
namedQuery: String(mapping.figshareScheduledTransitionRecordWorkflowFromArticlePropertiesJob?.namedQuery ?? ''),
|
|
328
|
+
targetStep: String(mapping.figshareScheduledTransitionRecordWorkflowFromArticlePropertiesJob?.targetStep ?? ''),
|
|
329
|
+
paramMap: mapping.figshareScheduledTransitionRecordWorkflowFromArticlePropertiesJob?.paramMap ?? {},
|
|
330
|
+
figshareTargetFieldKey: String(mapping.figshareScheduledTransitionRecordWorkflowFromArticlePropertiesJob?.figshareTargetFieldKey ?? ''),
|
|
331
|
+
figshareTargetFieldValue: String(mapping.figshareScheduledTransitionRecordWorkflowFromArticlePropertiesJob?.figshareTargetFieldValue ?? ''),
|
|
332
|
+
username: String(mapping.figshareScheduledTransitionRecordWorkflowFromArticlePropertiesJob?.username ?? ''),
|
|
333
|
+
userType: String(mapping.figshareScheduledTransitionRecordWorkflowFromArticlePropertiesJob?.userType ?? '')
|
|
334
|
+
}
|
|
335
|
+
},
|
|
336
|
+
testing: {
|
|
337
|
+
mode: figshareApi.testMode ? 'fixture' : 'live'
|
|
338
|
+
},
|
|
339
|
+
writeBack: {
|
|
340
|
+
articleId: 'metadata.figshare_article_id',
|
|
341
|
+
// The legacy article URL paths are write targets, so they belong to writeBack.
|
|
342
|
+
articleUrls: Array.isArray(mapping.recordFigArticleURL)
|
|
343
|
+
? mapping.recordFigArticleURL
|
|
344
|
+
: [typeof mapping.recordFigArticleURL === 'string' && mapping.recordFigArticleURL.trim() !== ''
|
|
345
|
+
? mapping.recordFigArticleURL
|
|
346
|
+
: 'metadata.figshare_article_location'],
|
|
347
|
+
extraFields: []
|
|
348
|
+
},
|
|
349
|
+
migrationReport: {
|
|
350
|
+
brand,
|
|
351
|
+
unsupportedLegacyTemplates: collectLegacyTemplates(mapping)
|
|
352
|
+
}
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
function registerMigrateFigshareConfigCommand(program) {
|
|
356
|
+
program
|
|
357
|
+
.command('migrate-figshare-config')
|
|
358
|
+
.description('Migrate legacy Figshare config into figsharePublishing AppConfig JSON files')
|
|
359
|
+
.requiredOption('--figshare-api <path>', 'Path to the legacy figshareAPI config module')
|
|
360
|
+
.option('--figshare-api-env <path>', 'Path to the legacy figshareAPIEnv config module')
|
|
361
|
+
.option('--figshare-for-mapping <path>', 'Path to the legacy figshareReDBoxFORMapping config module')
|
|
362
|
+
.requiredOption('-o, --output <path>', 'Directory to write migrated figsharePublishing JSON files')
|
|
363
|
+
.option('-b, --brands <brands...>', 'Brands to generate config for', ['default'])
|
|
364
|
+
.action(async (options) => {
|
|
365
|
+
try {
|
|
366
|
+
const globalOptions = program.opts();
|
|
367
|
+
const outputDir = path.resolve(options.output);
|
|
368
|
+
const brands = options.brands;
|
|
369
|
+
const figshareApi = pickLegacyExport(loadLegacyModule(options.figshareApi), 'figshareAPI');
|
|
370
|
+
const figshareApiEnv = options.figshareApiEnv
|
|
371
|
+
? pickLegacyExport(loadLegacyModule(options.figshareApiEnv), 'figshareAPIEnv')
|
|
372
|
+
: {};
|
|
373
|
+
const figshareForMapping = options.figshareForMapping
|
|
374
|
+
? pickLegacyExport(loadLegacyModule(options.figshareForMapping), 'figshareReDBoxFORMapping')
|
|
375
|
+
: {};
|
|
376
|
+
if (!globalOptions.dryRun) {
|
|
377
|
+
fs_1.default.mkdirSync(outputDir, { recursive: true });
|
|
378
|
+
}
|
|
379
|
+
const report = brands.map((brand) => {
|
|
380
|
+
const migrated = createMigratedFigsharePublishingConfig(brand, figshareApi, figshareApiEnv, figshareForMapping);
|
|
381
|
+
const outputPath = path.join(outputDir, `${brand}.figsharePublishing.json`);
|
|
382
|
+
if (!globalOptions.dryRun) {
|
|
383
|
+
fs_1.default.writeFileSync(outputPath, JSON.stringify(migrated, null, 2) + '\n', 'utf8');
|
|
384
|
+
}
|
|
385
|
+
return {
|
|
386
|
+
brand,
|
|
387
|
+
outputPath,
|
|
388
|
+
unsupportedLegacyTemplates: migrated.migrationReport.unsupportedLegacyTemplates
|
|
389
|
+
};
|
|
390
|
+
});
|
|
391
|
+
if (globalOptions.dryRun) {
|
|
392
|
+
console.log('[dry-run] Migration report generated; no files written.');
|
|
393
|
+
}
|
|
394
|
+
console.log(JSON.stringify(report, null, 2));
|
|
395
|
+
}
|
|
396
|
+
catch (error) {
|
|
397
|
+
console.error(`\n❌ Error: `, error);
|
|
398
|
+
process.exit(1);
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
declare const contentFormats: readonly ["plain", "html"];
|
|
3
|
+
type ContentFormats = typeof contentFormats[number];
|
|
4
|
+
type MetaEntryKey = string;
|
|
5
|
+
type MetaEntryValue = {
|
|
6
|
+
category?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
contentFormat?: ContentFormats;
|
|
9
|
+
};
|
|
10
|
+
export type MetaEntries = Record<MetaEntryKey, MetaEntryValue>;
|
|
11
|
+
export type MetaData = {
|
|
12
|
+
source: string;
|
|
13
|
+
data: MetaEntries;
|
|
14
|
+
};
|
|
15
|
+
export type TranslationLocaleRaw = {
|
|
16
|
+
locale: string;
|
|
17
|
+
source: string;
|
|
18
|
+
data: Record<string, unknown>;
|
|
19
|
+
};
|
|
20
|
+
export type TranslationEntries = Record<string, string>;
|
|
21
|
+
export type TranslationLocaleEntries = Record<string, TranslationEntries>;
|
|
22
|
+
export declare function registerSyncTranslationCommand(program: Command): void;
|
|
23
|
+
export {};
|