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 CHANGED
@@ -182,12 +182,12 @@ export class CSharpAst {
182
182
  // Ignore properties with these attributes on APIs
183
183
  ignoreCreateProps = [
184
184
  'autoIncrement',
185
- 'references',
185
+ 'reference',
186
186
  'compute',
187
187
  'computed',
188
188
  ].map(x => x.toLowerCase());
189
189
  ignoreUpdateProps = [
190
- 'references',
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 resolveMigrationFile(migrationPath) {
284
- return migrationPath.startsWith('~/')
285
- ? path.join(info.slnDir, trimStart(migrationPath, '~/'))
286
- : path.join(process.cwd(), migrationPath);
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 = resolveApiFile(header.api);
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 = resolveApiFile(header.migration);
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 = resolveMigrationFile(header.migration);
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 = resolveApiFile(header.api);
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(0);
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(0);
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) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "okai",
3
3
  "type": "module",
4
- "version": "0.0.26",
4
+ "version": "0.0.28",
5
5
  "bin": "./dist/okai.js",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",