okai 0.0.26 → 0.0.28
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/dist/cs-ast.js +2 -2
- package/dist/index.js +64 -50
- package/dist/info.js +4 -0
- package/dist/ts-ast.js +7 -1
- package/dist/ui-mjs.js +70 -0
- package/dist/utils.js +7 -0
- package/package.json +1 -1
package/dist/cs-ast.js
CHANGED
@@ -182,12 +182,12 @@ export class CSharpAst {
|
|
182
182
|
// Ignore properties with these attributes on APIs
|
183
183
|
ignoreCreateProps = [
|
184
184
|
'autoIncrement',
|
185
|
-
'
|
185
|
+
'reference',
|
186
186
|
'compute',
|
187
187
|
'computed',
|
188
188
|
].map(x => x.toLowerCase());
|
189
189
|
ignoreUpdateProps = [
|
190
|
-
'
|
190
|
+
'reference',
|
191
191
|
'compute',
|
192
192
|
'computed',
|
193
193
|
].map(x => x.toLowerCase());
|
package/dist/index.js
CHANGED
@@ -8,6 +8,7 @@ import { CSharpApiGenerator } from "./cs-apis.js";
|
|
8
8
|
import { CSharpMigrationGenerator } from "./cs-migrations.js";
|
9
9
|
import { getFileContent } from "./client.js";
|
10
10
|
import { toTsd } from "./tsd-gen.js";
|
11
|
+
import { UiMjsGroupGenerator, UiMjsIndexGenerator } from "./ui-mjs.js";
|
11
12
|
function normalizeSwitches(cmd) { return cmd.replace(/^-+/, '/'); }
|
12
13
|
function parseArgs(...args) {
|
13
14
|
const ret = {
|
@@ -147,6 +148,7 @@ export async function cli(cmdArgs) {
|
|
147
148
|
migrationsDir: "/path/to/MyApp/Migrations",
|
148
149
|
serviceModelDir: "/path/to/MyApp.ServiceModel",
|
149
150
|
serviceInterfaceDir: "/path/to/MyApp.ServiceInterfaces",
|
151
|
+
uiMjsDir: "/path/to/MyApp/wwwroot/admin/sections",
|
150
152
|
};
|
151
153
|
fs.writeFileSync('okai.json', JSON.stringify(info, undefined, 2));
|
152
154
|
console.log(`Added: okai.json`);
|
@@ -239,10 +241,14 @@ Options:
|
|
239
241
|
tsdAst.references.push({ path: './api.d.ts' });
|
240
242
|
}
|
241
243
|
tsd = toTsd(tsdAst);
|
244
|
+
let uiFileName = info.uiMjsDir
|
245
|
+
? path.join(info.uiMjsDir, `${groupName}.mjs`)
|
246
|
+
: null;
|
242
247
|
const tsdContent = createTsdFile(info, {
|
243
248
|
prompt: `New ${model}`,
|
244
249
|
apiFileName: `${groupName}.cs`,
|
245
250
|
tsd,
|
251
|
+
uiFileName,
|
246
252
|
});
|
247
253
|
command.type = "update"; // let update handle the rest
|
248
254
|
command.tsdFile = groupName + '.d.ts';
|
@@ -280,15 +286,10 @@ Options:
|
|
280
286
|
}
|
281
287
|
return tsdPath;
|
282
288
|
}
|
283
|
-
function
|
284
|
-
return
|
285
|
-
? path.join(info.slnDir, trimStart(
|
286
|
-
: path.join(process.cwd(),
|
287
|
-
}
|
288
|
-
function resolveApiFile(apiPath) {
|
289
|
-
return apiPath.startsWith('~/')
|
290
|
-
? path.join(info.slnDir, trimStart(apiPath, '~/'))
|
291
|
-
: path.join(process.cwd(), apiPath);
|
289
|
+
function resolveFile(filePath) {
|
290
|
+
return filePath.startsWith('~/')
|
291
|
+
? path.join(info.slnDir, trimStart(filePath, '~/'))
|
292
|
+
: path.join(process.cwd(), filePath);
|
292
293
|
}
|
293
294
|
if (command.type === "update") {
|
294
295
|
let tsdPath = assertTsdPath(command.tsdFile);
|
@@ -304,7 +305,7 @@ Options:
|
|
304
305
|
const genApis = new CSharpApiGenerator();
|
305
306
|
const csApiFiles = genApis.generate(result.csAst);
|
306
307
|
const apiContent = replaceMyApp(csApiFiles[Object.keys(csApiFiles)[0]], info.projectName);
|
307
|
-
const apiPath =
|
308
|
+
const apiPath = resolveFile(header.api);
|
308
309
|
console.log(`${logPrefix}${apiPath}`);
|
309
310
|
fs.writeFileSync(apiPath, apiContent, { encoding: 'utf-8' });
|
310
311
|
if (header?.migration) {
|
@@ -312,10 +313,23 @@ Options:
|
|
312
313
|
const getMigrations = new CSharpMigrationGenerator();
|
313
314
|
const csMigrationFiles = getMigrations.generate(result.csAst);
|
314
315
|
const migrationContent = replaceMyApp(csMigrationFiles[Object.keys(csMigrationFiles)[0]].replaceAll('Migration1000', migrationCls), info.projectName);
|
315
|
-
const migrationPath =
|
316
|
+
const migrationPath = resolveFile(header.migration);
|
316
317
|
console.log(`${logPrefix}${migrationPath}`);
|
317
318
|
fs.writeFileSync(migrationPath, migrationContent, { encoding: 'utf-8' });
|
318
319
|
}
|
320
|
+
if (header?.uiMjs) {
|
321
|
+
const uiMjsGroupPath = resolveFile(header.uiMjs);
|
322
|
+
const uiMjsGroupGen = new UiMjsGroupGenerator();
|
323
|
+
const uiMjsGroup = uiMjsGroupGen.generate(result.csAst, result.groupName);
|
324
|
+
console.log(`${logPrefix}${uiMjsGroupPath}`);
|
325
|
+
fs.writeFileSync(uiMjsGroupPath, uiMjsGroup, { encoding: 'utf-8' });
|
326
|
+
const uiMjsDir = path.dirname(uiMjsGroupPath);
|
327
|
+
const uiMjsIndexGen = new UiMjsIndexGenerator();
|
328
|
+
const uiMjsIndex = uiMjsIndexGen.generate(fs.readdirSync(uiMjsDir));
|
329
|
+
const uiMjsIndexPath = path.join(uiMjsDir, 'index.mjs');
|
330
|
+
console.log(`${logPrefix}${uiMjsIndexPath}`);
|
331
|
+
fs.writeFileSync(uiMjsIndexPath, uiMjsIndex, { encoding: 'utf-8' });
|
332
|
+
}
|
319
333
|
console.log(`${logPrefix}${tsdPath}`);
|
320
334
|
const newTsdContent = toTsdHeader(header) + (tsdContent.startsWith('///') ? '' : '\n\n') + tsdContent;
|
321
335
|
fs.writeFileSync(tsdPath, newTsdContent, { encoding: 'utf-8' });
|
@@ -353,7 +367,7 @@ Options:
|
|
353
367
|
if (command.verbose)
|
354
368
|
console.log(JSON.stringify(header, undefined, 2));
|
355
369
|
if (header?.migration) {
|
356
|
-
const migrationPath =
|
370
|
+
const migrationPath = resolveFile(header.migration);
|
357
371
|
if (fs.existsSync(migrationPath)) {
|
358
372
|
fs.unlinkSync(migrationPath);
|
359
373
|
console.log(`Removed: ${migrationPath}`);
|
@@ -363,7 +377,7 @@ Options:
|
|
363
377
|
}
|
364
378
|
}
|
365
379
|
if (header?.api) {
|
366
|
-
const apiPath =
|
380
|
+
const apiPath = resolveFile(header.api);
|
367
381
|
if (fs.existsSync(apiPath)) {
|
368
382
|
fs.unlinkSync(apiPath);
|
369
383
|
console.log(`Removed: ${apiPath}`);
|
@@ -372,6 +386,21 @@ Options:
|
|
372
386
|
console.log(`APIs .cs file not found: ${apiPath}`);
|
373
387
|
}
|
374
388
|
}
|
389
|
+
if (header?.uiMjs) {
|
390
|
+
const uiMjsGroupPath = resolveFile(header.uiMjs);
|
391
|
+
if (fs.existsSync(uiMjsGroupPath)) {
|
392
|
+
fs.unlinkSync(uiMjsGroupPath);
|
393
|
+
console.log(`Removed: ${uiMjsGroupPath}`);
|
394
|
+
const uiMjsDir = path.dirname(uiMjsGroupPath);
|
395
|
+
const uiMjsIndexGen = new UiMjsIndexGenerator();
|
396
|
+
const uiMjsIndex = uiMjsIndexGen.generate(fs.readdirSync(uiMjsDir));
|
397
|
+
const uiMjsIndexPath = path.join(uiMjsDir, 'index.mjs');
|
398
|
+
fs.writeFileSync(uiMjsIndexPath, uiMjsIndex, { encoding: 'utf-8' });
|
399
|
+
}
|
400
|
+
else {
|
401
|
+
console.log(`UI .mjs file not found: ${uiMjsGroupPath}`);
|
402
|
+
}
|
403
|
+
}
|
375
404
|
fs.unlinkSync(tsdPath);
|
376
405
|
console.log(`Removed: ${tsdPath}`);
|
377
406
|
const serviceModelDir = path.dirname(tsdPath);
|
@@ -653,7 +682,7 @@ function chooseFile(ctx, info, gist, comamnd) {
|
|
653
682
|
}
|
654
683
|
const origTsd = file.content;
|
655
684
|
const tsdAst = astForProject(toAst(origTsd), info);
|
656
|
-
const res = generateCsAstFromTsd(toTsd(tsdAst));
|
685
|
+
const res = generateCsAstFromTsd(toTsd(tsdAst), { references: [`./api.d.ts`] });
|
657
686
|
const genApis = new CSharpApiGenerator();
|
658
687
|
const csApiFiles = genApis.generate(res.csAst);
|
659
688
|
const getMigrations = new CSharpMigrationGenerator();
|
@@ -669,10 +698,22 @@ function chooseFile(ctx, info, gist, comamnd) {
|
|
669
698
|
const apiTypesPath = path.join(info.slnDir, relativeServiceModelDir, `api.d.ts`);
|
670
699
|
const apiFile = path.join(import.meta.dirname, 'api.d.ts');
|
671
700
|
fs.writeFileSync(apiTypesPath, fs.readFileSync(apiFile, 'utf-8'));
|
701
|
+
let uiFileName = null;
|
702
|
+
if (info.uiMjsDir) {
|
703
|
+
uiFileName = `${res.groupName}.mjs`;
|
704
|
+
const uiGroupPath = path.join(info.uiMjsDir, uiFileName);
|
705
|
+
const uiVueGen = new UiMjsGroupGenerator();
|
706
|
+
const uiGroupSrc = uiVueGen.generate(res.csAst, res.groupName);
|
707
|
+
fs.writeFileSync(uiGroupPath, uiGroupSrc);
|
708
|
+
const uiIndexGen = new UiMjsIndexGenerator();
|
709
|
+
const uiIndexSrc = uiIndexGen.generate(fs.readdirSync(info.uiMjsDir));
|
710
|
+
fs.writeFileSync(path.join(info.uiMjsDir, `index.mjs`), uiIndexSrc);
|
711
|
+
}
|
672
712
|
const tsdContent = createTsdFile(info, {
|
673
713
|
prompt: titleBar.content.replaceAll('/*', '').replaceAll('*/', ''),
|
674
714
|
apiFileName,
|
675
715
|
tsd: res.tsd,
|
716
|
+
uiFileName,
|
676
717
|
});
|
677
718
|
const tsdFileName = `${res.groupName}.d.ts`;
|
678
719
|
const fullTsdPath = path.join(info.slnDir, relativeServiceModelDir, tsdFileName);
|
@@ -680,7 +721,7 @@ function chooseFile(ctx, info, gist, comamnd) {
|
|
680
721
|
const fullMigrationPath = path.join(info.slnDir, relativeMigrationDir, migrationFileName);
|
681
722
|
if (!fs.existsSync(path.dirname(fullTsdPath))) {
|
682
723
|
console.log(`Directory does not exist: ${path.dirname(fullTsdPath)}`);
|
683
|
-
process.exit(
|
724
|
+
process.exit(1);
|
684
725
|
}
|
685
726
|
console.log(`\nSelected '${result.selectedFile}' data models`);
|
686
727
|
fs.writeFileSync(fullTsdPath, tsdContent, { encoding: 'utf-8' });
|
@@ -692,6 +733,7 @@ function chooseFile(ctx, info, gist, comamnd) {
|
|
692
733
|
if (fs.existsSync(path.dirname(fullMigrationPath))) {
|
693
734
|
fs.writeFileSync(fullMigrationPath, migrationContent, { encoding: 'utf-8' });
|
694
735
|
console.log(`Saved: ${fullMigrationPath}`);
|
736
|
+
console.log(`\nRun 'dotnet run --AppTasks=migrate' to apply the new migration and create the new tables`);
|
695
737
|
}
|
696
738
|
const script = path.basename(process.argv[1]);
|
697
739
|
console.log(`\nTo regenerate classes, update '${tsdFileName}' then run:`);
|
@@ -706,7 +748,7 @@ function chooseFile(ctx, info, gist, comamnd) {
|
|
706
748
|
.catch((err) => {
|
707
749
|
if (comamnd.verbose)
|
708
750
|
console.log(`ERROR: ${err.message ?? err}`);
|
709
|
-
process.exit(
|
751
|
+
process.exit(1);
|
710
752
|
});
|
711
753
|
}
|
712
754
|
else {
|
@@ -773,6 +815,9 @@ function createTsdFile(info, opt) {
|
|
773
815
|
const relativeMigrationDir = info.migrationsDir && fs.existsSync(info.migrationsDir)
|
774
816
|
? trimStart(info.migrationsDir.substring(info.slnDir.length), '~/')
|
775
817
|
: null;
|
818
|
+
const relativeUiVueDir = opt.uiFileName && info.uiMjsDir && fs.existsSync(info.uiMjsDir)
|
819
|
+
? trimStart(info.uiMjsDir.substring(info.slnDir.length), '~/')
|
820
|
+
: null;
|
776
821
|
const sb = [
|
777
822
|
`/*prompt: ${opt.prompt}`,
|
778
823
|
`api: ~/${path.join(relativeServiceModelDir, opt.apiFileName)}`,
|
@@ -780,41 +825,10 @@ function createTsdFile(info, opt) {
|
|
780
825
|
if (relativeMigrationDir) {
|
781
826
|
sb.push(`migration: ~/${path.join(relativeMigrationDir, migrationFileName)}`);
|
782
827
|
}
|
828
|
+
if (relativeUiVueDir) {
|
829
|
+
sb.push(`ui.mjs: ~/${path.join(relativeUiVueDir, opt.uiFileName)}`);
|
830
|
+
}
|
783
831
|
sb.push('*/');
|
784
832
|
sb.push('');
|
785
833
|
return sb.join('\n') + (opt.tsd.startsWith('///') ? '' : '\n\n') + opt.tsd;
|
786
834
|
}
|
787
|
-
function applyCSharpGist(ctx, info, gist, { accept = false, acceptAll = false, discard = false }) {
|
788
|
-
const { screen, titleBar, fileList, preview, statusBar, result } = ctx;
|
789
|
-
function removeSelected() {
|
790
|
-
delete gist.files[result.selectedFile];
|
791
|
-
fileList.removeItem(result.selectedFile);
|
792
|
-
const nextFile = Object.keys(gist.files)[0];
|
793
|
-
if (nextFile) {
|
794
|
-
result.selectedFile = nextFile;
|
795
|
-
const nextFileIndex = fileList.getItemIndex(nextFile);
|
796
|
-
fileList.select(nextFileIndex);
|
797
|
-
preview.setContent(gist.files[nextFile].content);
|
798
|
-
}
|
799
|
-
screen.render();
|
800
|
-
if (Object.keys(gist.files).length === 0) {
|
801
|
-
//screen.destroy()
|
802
|
-
exit(screen, info, gist);
|
803
|
-
}
|
804
|
-
}
|
805
|
-
if (discard) {
|
806
|
-
const file = gist.files[result.selectedFile];
|
807
|
-
removeSelected();
|
808
|
-
}
|
809
|
-
else if (accept) {
|
810
|
-
const file = gist.files[result.selectedFile];
|
811
|
-
writeFile(info, result.selectedFile, file.content);
|
812
|
-
removeSelected();
|
813
|
-
}
|
814
|
-
else if (acceptAll) {
|
815
|
-
for (const [filename, file] of Object.entries(gist.files)) {
|
816
|
-
writeFile(info, filename, file.content);
|
817
|
-
}
|
818
|
-
exit(screen, info, gist);
|
819
|
-
}
|
820
|
-
}
|
package/dist/info.js
CHANGED
@@ -53,6 +53,10 @@ export function projectInfo(cwd) {
|
|
53
53
|
serviceModelDir,
|
54
54
|
serviceInterfaceDir,
|
55
55
|
};
|
56
|
+
const uiVueDir = path.join(hostDir, "wwwroot", "admin", "sections");
|
57
|
+
if (fs.existsSync(uiVueDir)) {
|
58
|
+
info.uiMjsDir = uiVueDir;
|
59
|
+
}
|
56
60
|
for (const file of walk(serviceInterfaceDir, [], {
|
57
61
|
include: (path) => path.endsWith(".cs"),
|
58
62
|
excludeDirs: ["obj", "bin"]
|
package/dist/ts-ast.js
CHANGED
@@ -34,8 +34,14 @@ export function astForProject(tsAst, info) {
|
|
34
34
|
return tsAst;
|
35
35
|
}
|
36
36
|
// Convert User TypeScript into CS AST and Updated TSD
|
37
|
-
export function generateCsAstFromTsd(userTs) {
|
37
|
+
export function generateCsAstFromTsd(userTs, opt) {
|
38
38
|
const userTsAst = toAst(userTs); // user modified tsd
|
39
|
+
if (opt?.references) {
|
40
|
+
userTsAst.references = userTsAst.references || [];
|
41
|
+
opt.references
|
42
|
+
.filter(x => !userTsAst.references.some(y => y.path === x))
|
43
|
+
.forEach(path => userTsAst.references.push({ path }));
|
44
|
+
}
|
39
45
|
const tsd = toTsd(userTsAst);
|
40
46
|
const tsdAst = toAst(tsd);
|
41
47
|
const csAst = toMetadataTypes(tsdAst);
|
package/dist/ui-mjs.js
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
import { getGroupName, plural, toCamelCase } from "./utils.js";
|
2
|
+
/*
|
3
|
+
export default {
|
4
|
+
group: "Bookings",
|
5
|
+
items: {
|
6
|
+
Bookings: {
|
7
|
+
type: 'Booking',
|
8
|
+
component: {
|
9
|
+
template:`<AutoQueryGrid :type="type"
|
10
|
+
selected-columns="id,name,roomType,roomNumber,bookingStartDate,bookingEndDate,cost,couponId,discount" />`,
|
11
|
+
},
|
12
|
+
},
|
13
|
+
Coupons: {
|
14
|
+
type: 'Coupon',
|
15
|
+
component: {
|
16
|
+
template:`<AutoQueryGrid :type="type"
|
17
|
+
selected-columns="id,name,description,discount,expiryDate" />`,
|
18
|
+
},
|
19
|
+
},
|
20
|
+
},
|
21
|
+
}
|
22
|
+
*/
|
23
|
+
export class UiMjsGroupGenerator {
|
24
|
+
generate(ast, groupLabel) {
|
25
|
+
if (!groupLabel) {
|
26
|
+
const groupName = getGroupName(ast);
|
27
|
+
groupLabel = plural(groupName);
|
28
|
+
}
|
29
|
+
const sb = [
|
30
|
+
`export default {`,
|
31
|
+
` group: "${groupLabel}",`,
|
32
|
+
` items: {`,
|
33
|
+
...ast.types.filter(x => !x.isEnum && !x.isInterface).map(x => {
|
34
|
+
return [
|
35
|
+
` ${plural(x.name)}: {`,
|
36
|
+
` type: '${x.name}',`,
|
37
|
+
` component: {`,
|
38
|
+
` template:\`<AutoQueryGrid :type="type"`,
|
39
|
+
` selected-columns="${x.properties.map(x => toCamelCase(x.name)).join(',')}" />\`,`,
|
40
|
+
` },`,
|
41
|
+
` },`,
|
42
|
+
].join('\n');
|
43
|
+
}),
|
44
|
+
` }`,
|
45
|
+
`}`,
|
46
|
+
];
|
47
|
+
const src = sb.join('\n');
|
48
|
+
return src;
|
49
|
+
}
|
50
|
+
}
|
51
|
+
/*
|
52
|
+
import Bookings from './Bookings.mjs'
|
53
|
+
export {
|
54
|
+
Bookings,
|
55
|
+
}
|
56
|
+
*/
|
57
|
+
export class UiMjsIndexGenerator {
|
58
|
+
generate(files) {
|
59
|
+
const imports = [];
|
60
|
+
const exports = ['export {'];
|
61
|
+
files.filter(x => x != 'index.mjs').forEach(x => {
|
62
|
+
const name = x.replace('.mjs', '');
|
63
|
+
imports.push(`import ${name} from './${name}.mjs'`);
|
64
|
+
exports.push(` ${name},`);
|
65
|
+
});
|
66
|
+
exports.push('}');
|
67
|
+
const src = imports.join('\n') + '\n' + exports.join('\n');
|
68
|
+
return src;
|
69
|
+
}
|
70
|
+
}
|
package/dist/utils.js
CHANGED
@@ -178,6 +178,9 @@ export function parseTsdHeader(tsd) {
|
|
178
178
|
else if (line.startsWith('migration:')) {
|
179
179
|
to.migration = line.replace('migration:', '').trim();
|
180
180
|
}
|
181
|
+
else if (line.startsWith('ui.mjs:')) {
|
182
|
+
to.uiMjs = line.replace('ui.mjs:', '').trim();
|
183
|
+
}
|
181
184
|
else if (!to.api && !to.migration && line.trim()) {
|
182
185
|
to.prompt += line.trim() + '\n';
|
183
186
|
}
|
@@ -198,7 +201,11 @@ export function toTsdHeader(header) {
|
|
198
201
|
if (header.migration) {
|
199
202
|
sb.push(`migration: ${header.migration}`);
|
200
203
|
}
|
204
|
+
if (header.uiMjs) {
|
205
|
+
sb.push(`ui.mjs: ${header.uiMjs}`);
|
206
|
+
}
|
201
207
|
sb.push('*/');
|
208
|
+
sb.push('');
|
202
209
|
return sb.join('\n');
|
203
210
|
}
|
204
211
|
export function toPascalCase(s) {
|