zenstack 0.1.12 → 0.1.13

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.
Files changed (34) hide show
  1. package/out/generator/index.js +1 -3
  2. package/out/generator/index.js.map +1 -1
  3. package/package.json +2 -3
  4. package/src/cli/cli-util.ts +0 -80
  5. package/src/cli/index.ts +0 -52
  6. package/src/extension.ts +0 -76
  7. package/src/generator/constants.ts +0 -2
  8. package/src/generator/index.ts +0 -76
  9. package/src/generator/next-auth/index.ts +0 -183
  10. package/src/generator/package.template.json +0 -9
  11. package/src/generator/prisma/expression-writer.ts +0 -352
  12. package/src/generator/prisma/index.ts +0 -24
  13. package/src/generator/prisma/plain-expression-builder.ts +0 -91
  14. package/src/generator/prisma/prisma-builder.ts +0 -366
  15. package/src/generator/prisma/query-gard-generator.ts +0 -208
  16. package/src/generator/prisma/schema-generator.ts +0 -295
  17. package/src/generator/react-hooks/index.ts +0 -265
  18. package/src/generator/service/index.ts +0 -96
  19. package/src/generator/tsconfig.template.json +0 -17
  20. package/src/generator/types.ts +0 -16
  21. package/src/generator/utils.ts +0 -9
  22. package/src/language-server/generated/ast.ts +0 -603
  23. package/src/language-server/generated/grammar.ts +0 -2190
  24. package/src/language-server/generated/module.ts +0 -24
  25. package/src/language-server/main.ts +0 -12
  26. package/src/language-server/stdlib.zmodel +0 -21
  27. package/src/language-server/types.ts +0 -9
  28. package/src/language-server/zmodel-index.ts +0 -33
  29. package/src/language-server/zmodel-linker.ts +0 -407
  30. package/src/language-server/zmodel-module.ts +0 -90
  31. package/src/language-server/zmodel-scope.ts +0 -21
  32. package/src/language-server/zmodel-validator.ts +0 -35
  33. package/src/language-server/zmodel.langium +0 -186
  34. package/src/utils/indent-string.ts +0 -6
@@ -69,13 +69,11 @@ class ZenStackGenerator {
69
69
  // compile ts sources
70
70
  const tsConfig = require(path_1.default.join(__dirname, 'tsconfig.template.json'));
71
71
  fs.writeFileSync(path_1.default.join(context.outDir, 'tsconfig.json'), JSON.stringify(tsConfig, undefined, 4));
72
- let tscOutput = '';
73
72
  try {
74
- tscOutput = (0, child_process_1.execSync)(`npx tsc -p "${path_1.default.join(context.outDir, 'tsconfig.json')}"`, { encoding: 'utf-8' });
73
+ (0, child_process_1.execSync)(`npx tsc -p "${path_1.default.join(context.outDir, 'tsconfig.json')}"`, { encoding: 'utf-8', stdio: 'inherit' });
75
74
  }
76
75
  catch (_a) {
77
76
  console.error(colors_1.default.red('Something went wrong, generated runtime code failed to compile...'));
78
- console.log(tscOutput);
79
77
  return;
80
78
  }
81
79
  console.log(colors_1.default.blue(' ✔️ Typescript source files transpiled'));
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generator/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,uCAAyB;AACzB,oDAA4B;AAC5B,sDAAuC;AACvC,wDAAyC;AACzC,gEAAgD;AAChD,4DAA4C;AAC5C,gDAAwB;AACxB,iDAAyC;AAEzC,MAAa,iBAAiB;IACpB,QAAQ,CAAC,OAAgB;;YAC3B,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;gBAC/B,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;aAC/D;iBAAM;gBACH,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;aAChC;YAED,OAAO,CAAC,GAAG,CAAC,gBAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC,CAAC;YAE3D,MAAM,UAAU,GAAG;gBACf,IAAI,gBAAe,EAAE;gBACrB,IAAI,iBAAgB,EAAE;gBACtB,IAAI,qBAAmB,EAAE;gBACzB,IAAI,mBAAiB,EAAE;aAC1B,CAAC;YAEF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE;gBAChC,MAAM,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;aACrC;YAED,wBAAwB;YACxB,MAAM,WAAW,GAAG,OAAO,CAAC,cAAI,CAAC,IAAI,CACjC,SAAS,EACT,uBAAuB,CAC1B,CAAC,CAAC;YACH,EAAE,CAAC,aAAa,CACZ,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,cAAc,CAAC,EACzC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC,CAC5C,CAAC;YAEF,qBAAqB;YACrB,MAAM,QAAQ,GAAG,OAAO,CAAC,cAAI,CAAC,IAAI,CAC9B,SAAS,EACT,wBAAwB,CAC3B,CAAC,CAAC;YACH,EAAE,CAAC,aAAa,CACZ,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,eAAe,CAAC,EAC1C,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,CACzC,CAAC;YAEF,IAAI,SAAS,GAAG,EAAE,CAAC;YACnB,IAAI;gBACA,SAAS,GAAG,IAAA,wBAAQ,EAChB,eAAe,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,EAC5D,EAAE,QAAQ,EAAE,OAAO,EAAE,CACxB,CAAC;aACL;YAAC,WAAM;gBACJ,OAAO,CAAC,KAAK,CACT,gBAAM,CAAC,GAAG,CACN,mEAAmE,CACtE,CACJ,CAAC;gBACF,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBACvB,OAAO;aACV;YAED,OAAO,CAAC,GAAG,CAAC,gBAAM,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC,CAAC;YAEpE,OAAO,CAAC,GAAG,CACP,gBAAM,CAAC,KAAK,CACR,gBAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAC3D,CACJ,CAAC;QACN,CAAC;KAAA;CACJ;AAjED,8CAiEC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generator/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,uCAAyB;AACzB,oDAA4B;AAC5B,sDAAuC;AACvC,wDAAyC;AACzC,gEAAgD;AAChD,4DAA4C;AAC5C,gDAAwB;AACxB,iDAAyC;AAEzC,MAAa,iBAAiB;IACpB,QAAQ,CAAC,OAAgB;;YAC3B,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;gBAC/B,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;aAC/D;iBAAM;gBACH,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;aAChC;YAED,OAAO,CAAC,GAAG,CAAC,gBAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC,CAAC;YAE3D,MAAM,UAAU,GAAG;gBACf,IAAI,gBAAe,EAAE;gBACrB,IAAI,iBAAgB,EAAE;gBACtB,IAAI,qBAAmB,EAAE;gBACzB,IAAI,mBAAiB,EAAE;aAC1B,CAAC;YAEF,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE;gBAChC,MAAM,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;aACrC;YAED,wBAAwB;YACxB,MAAM,WAAW,GAAG,OAAO,CAAC,cAAI,CAAC,IAAI,CACjC,SAAS,EACT,uBAAuB,CAC1B,CAAC,CAAC;YACH,EAAE,CAAC,aAAa,CACZ,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,cAAc,CAAC,EACzC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC,CAC5C,CAAC;YAEF,qBAAqB;YACrB,MAAM,QAAQ,GAAG,OAAO,CAAC,cAAI,CAAC,IAAI,CAC9B,SAAS,EACT,wBAAwB,CAC3B,CAAC,CAAC;YACH,EAAE,CAAC,aAAa,CACZ,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,eAAe,CAAC,EAC1C,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC,CACzC,CAAC;YAEF,IAAI;gBACA,IAAA,wBAAQ,EACJ,eAAe,cAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,eAAe,CAAC,GAAG,EAC5D,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAC1C,CAAC;aACL;YAAC,WAAM;gBACJ,OAAO,CAAC,KAAK,CACT,gBAAM,CAAC,GAAG,CACN,mEAAmE,CACtE,CACJ,CAAC;gBACF,OAAO;aACV;YAED,OAAO,CAAC,GAAG,CAAC,gBAAM,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC,CAAC;YAEpE,OAAO,CAAC,GAAG,CACP,gBAAM,CAAC,KAAK,CACR,gBAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAC3D,CACJ,CAAC;QACN,CAAC;KAAA;CACJ;AA/DD,8CA+DC"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "zenstack",
3
3
  "displayName": "ZenStack CLI and Language Tools",
4
4
  "description": "ZenStack CLI and Language Tools",
5
- "version": "0.1.12",
5
+ "version": "0.1.13",
6
6
  "engines": {
7
7
  "vscode": "^1.56.0"
8
8
  },
@@ -40,8 +40,7 @@
40
40
  ],
41
41
  "files": [
42
42
  "bin",
43
- "out",
44
- "src"
43
+ "out"
45
44
  ],
46
45
  "bin": {
47
46
  "zenstack": "./bin/cli"
@@ -1,80 +0,0 @@
1
- import colors from 'colors';
2
- import path from 'path';
3
- import fs from 'fs';
4
- import { AstNode, LangiumDocument, LangiumServices } from 'langium';
5
- import { URI } from 'vscode-uri';
6
-
7
- export async function extractDocument(
8
- fileName: string,
9
- services: LangiumServices
10
- ): Promise<LangiumDocument> {
11
- const extensions = services.LanguageMetaData.fileExtensions;
12
- if (!extensions.includes(path.extname(fileName))) {
13
- console.error(
14
- colors.yellow(
15
- `Please choose a file with one of these extensions: ${extensions}.`
16
- )
17
- );
18
- process.exit(1);
19
- }
20
-
21
- if (!fs.existsSync(fileName)) {
22
- console.error(colors.red(`File ${fileName} does not exist.`));
23
- process.exit(1);
24
- }
25
-
26
- const stdLib =
27
- services.shared.workspace.LangiumDocuments.getOrCreateDocument(
28
- URI.file(path.join(__dirname, '../language-server/stdlib.zmodel'))
29
- );
30
- const document =
31
- services.shared.workspace.LangiumDocuments.getOrCreateDocument(
32
- URI.file(path.resolve(fileName))
33
- );
34
- await services.shared.workspace.DocumentBuilder.build([stdLib, document], {
35
- validationChecks: 'all',
36
- });
37
-
38
- const validationErrors = (document.diagnostics ?? []).filter(
39
- (e) => e.severity === 1
40
- );
41
- if (validationErrors.length > 0) {
42
- console.error(colors.red('There are validation errors:'));
43
- for (const validationError of validationErrors) {
44
- console.error(
45
- colors.red(
46
- `line ${validationError.range.start.line + 1}: ${
47
- validationError.message
48
- } [${document.textDocument.getText(validationError.range)}]`
49
- )
50
- );
51
- }
52
- process.exit(1);
53
- }
54
-
55
- return document;
56
- }
57
-
58
- export async function extractAstNode<T extends AstNode>(
59
- fileName: string,
60
- services: LangiumServices
61
- ): Promise<T> {
62
- return (await extractDocument(fileName, services)).parseResult?.value as T;
63
- }
64
-
65
- interface FilePathData {
66
- destination: string;
67
- name: string;
68
- }
69
-
70
- export function extractDestinationAndName(
71
- filePath: string,
72
- destination: string | undefined
73
- ): FilePathData {
74
- filePath = filePath.replace(/\..*$/, '').replace(/[.-]/g, '');
75
- return {
76
- destination:
77
- destination ?? path.join(path.dirname(filePath), 'generated'),
78
- name: path.basename(filePath),
79
- };
80
- }
package/src/cli/index.ts DELETED
@@ -1,52 +0,0 @@
1
- import { Command } from 'commander';
2
- import { Model } from '../language-server/generated/ast';
3
- import { ZModelLanguageMetaData } from '../language-server/generated/module';
4
- import { createZModelServices } from '../language-server/zmodel-module';
5
- import { extractAstNode } from './cli-util';
6
- import { Context } from '../generator/types';
7
- import { ZenStackGenerator } from '../generator';
8
-
9
- export const generateAction = async (
10
- fileName: string,
11
- opts: GenerateOptions
12
- ): Promise<void> => {
13
- const services = createZModelServices().ZModel;
14
- const model = await extractAstNode<Model>(fileName, services);
15
-
16
- const context: Context = {
17
- schema: model,
18
- outDir: opts.destination || 'node_modules/.zenstack',
19
- };
20
-
21
- await new ZenStackGenerator().generate(context);
22
- };
23
-
24
- export type GenerateOptions = {
25
- destination?: string;
26
- };
27
-
28
- export default function (): void {
29
- const program = new Command();
30
-
31
- program
32
- // eslint-disable-next-line @typescript-eslint/no-var-requires
33
- .version(require('../../package.json').version);
34
-
35
- const fileExtensions = ZModelLanguageMetaData.fileExtensions.join(', ');
36
- program
37
- .command('generate')
38
- .argument(
39
- '<file>',
40
- `source file (possible file extensions: ${fileExtensions})`
41
- )
42
- .option(
43
- '-d, --destination <dir>',
44
- 'destination directory of generating'
45
- )
46
- .description(
47
- 'generates JavaScript code that prints "Hello, {name}!" for each greeting in a source file'
48
- )
49
- .action(generateAction);
50
-
51
- program.parse(process.argv);
52
- }
package/src/extension.ts DELETED
@@ -1,76 +0,0 @@
1
- import * as vscode from 'vscode';
2
- import * as path from 'path';
3
- import {
4
- LanguageClient,
5
- LanguageClientOptions,
6
- ServerOptions,
7
- TransportKind,
8
- } from 'vscode-languageclient/node';
9
-
10
- let client: LanguageClient;
11
-
12
- // This function is called when the extension is activated.
13
- export function activate(context: vscode.ExtensionContext): void {
14
- client = startLanguageClient(context);
15
- }
16
-
17
- // This function is called when the extension is deactivated.
18
- export function deactivate(): Thenable<void> | undefined {
19
- if (client) {
20
- return client.stop();
21
- }
22
- return undefined;
23
- }
24
-
25
- function startLanguageClient(context: vscode.ExtensionContext): LanguageClient {
26
- const serverModule = context.asAbsolutePath(
27
- path.join('out', 'language-server', 'main')
28
- );
29
- // The debug options for the server
30
- // --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging.
31
- // By setting `process.env.DEBUG_BREAK` to a truthy value, the language server will wait until a debugger is attached.
32
- const debugOptions = {
33
- execArgv: [
34
- '--nolazy',
35
- `--inspect${process.env.DEBUG_BREAK ? '-brk' : ''}=${
36
- process.env.DEBUG_SOCKET || '6009'
37
- }`,
38
- ],
39
- };
40
-
41
- // If the extension is launched in debug mode then the debug server options are used
42
- // Otherwise the run options are used
43
- const serverOptions: ServerOptions = {
44
- run: { module: serverModule, transport: TransportKind.ipc },
45
- debug: {
46
- module: serverModule,
47
- transport: TransportKind.ipc,
48
- options: debugOptions,
49
- },
50
- };
51
-
52
- const fileSystemWatcher =
53
- vscode.workspace.createFileSystemWatcher('**/*.zmodel');
54
- context.subscriptions.push(fileSystemWatcher);
55
-
56
- // Options to control the language client
57
- const clientOptions: LanguageClientOptions = {
58
- documentSelector: [{ scheme: 'file', language: 'zmodel' }],
59
- synchronize: {
60
- // Notify the server about file changes to files contained in the workspace
61
- fileEvents: fileSystemWatcher,
62
- },
63
- };
64
-
65
- // Create the language client and start the client.
66
- const client = new LanguageClient(
67
- 'zmodel',
68
- 'ZenStack Model',
69
- serverOptions,
70
- clientOptions
71
- );
72
-
73
- // Start the client. This will also launch the server
74
- client.start();
75
- return client;
76
- }
@@ -1,2 +0,0 @@
1
- export const RUNTIME_PACKAGE = '@zenstackhq/runtime';
2
- export const GUARD_FIELD_NAME = 'zenstack_guard';
@@ -1,76 +0,0 @@
1
- import { Context } from './types';
2
- import * as fs from 'fs';
3
- import colors from 'colors';
4
- import PrismaGenerator from './prisma';
5
- import ServiceGenerator from './service';
6
- import ReactHooksGenerator from './react-hooks';
7
- import NextAuthGenerator from './next-auth';
8
- import path from 'path';
9
- import { execSync } from 'child_process';
10
-
11
- export class ZenStackGenerator {
12
- async generate(context: Context) {
13
- if (fs.existsSync(context.outDir)) {
14
- fs.rmSync(context.outDir, { force: true, recursive: true });
15
- } else {
16
- fs.mkdirSync(context.outDir);
17
- }
18
-
19
- console.log(colors.bold('⌛️ Running ZenStack generators'));
20
-
21
- const generators = [
22
- new PrismaGenerator(),
23
- new ServiceGenerator(),
24
- new ReactHooksGenerator(),
25
- new NextAuthGenerator(),
26
- ];
27
-
28
- for (const generator of generators) {
29
- await generator.generate(context);
30
- }
31
-
32
- // generate package.json
33
- const packageJson = require(path.join(
34
- __dirname,
35
- 'package.template.json'
36
- ));
37
- fs.writeFileSync(
38
- path.join(context.outDir, 'package.json'),
39
- JSON.stringify(packageJson, undefined, 4)
40
- );
41
-
42
- // compile ts sources
43
- const tsConfig = require(path.join(
44
- __dirname,
45
- 'tsconfig.template.json'
46
- ));
47
- fs.writeFileSync(
48
- path.join(context.outDir, 'tsconfig.json'),
49
- JSON.stringify(tsConfig, undefined, 4)
50
- );
51
-
52
- let tscOutput = '';
53
- try {
54
- tscOutput = execSync(
55
- `npx tsc -p "${path.join(context.outDir, 'tsconfig.json')}"`,
56
- { encoding: 'utf-8' }
57
- );
58
- } catch {
59
- console.error(
60
- colors.red(
61
- 'Something went wrong, generated runtime code failed to compile...'
62
- )
63
- );
64
- console.log(tscOutput);
65
- return;
66
- }
67
-
68
- console.log(colors.blue(' ✔️ Typescript source files transpiled'));
69
-
70
- console.log(
71
- colors.green(
72
- colors.bold('👻 All generators completed successfully!')
73
- )
74
- );
75
- }
76
- }
@@ -1,183 +0,0 @@
1
- import { Context, Generator } from '../types';
2
- import { Project } from 'ts-morph';
3
- import * as path from 'path';
4
-
5
- export default class NextAuthGenerator implements Generator {
6
- async generate(context: Context) {
7
- const project = new Project();
8
-
9
- this.generateIndex(project, context);
10
- this.generateAdapter(project, context);
11
- this.generateAuthorize(project, context);
12
-
13
- await project.save();
14
- }
15
-
16
- generateIndex(project: Project, context: Context) {
17
- const sf = project.createSourceFile(
18
- path.join(context.outDir, 'auth/index.ts'),
19
- undefined,
20
- { overwrite: true }
21
- );
22
-
23
- sf.addStatements([
24
- `export * from './next-auth-adapter';`,
25
- `export * from './authorize';`,
26
- ]);
27
-
28
- sf.formatText();
29
- }
30
-
31
- generateAdapter(project: Project, context: Context) {
32
- const content = `
33
- import { ZenStackService } from '..';
34
- import { Adapter } from 'next-auth/adapters';
35
- import { Prisma } from '../.prisma';
36
-
37
- export function NextAuthAdapter(service: ZenStackService): Adapter {
38
- const db = service.db;
39
- return {
40
- createUser: (data) => db.user.create({ data: data as Prisma.UserCreateInput }),
41
- getUser: (id) => db.user.findUnique({ where: { id } }),
42
- getUserByEmail: (email) => db.user.findUnique({ where: { email } }),
43
- async getUserByAccount(provider_providerAccountId) {
44
- const account = await db.account.findUnique({
45
- where: { provider_providerAccountId },
46
- select: { user: true },
47
- });
48
- return account?.user ?? null;
49
- },
50
- updateUser: (data) => db.user.update({ where: { id: data.id }, data: data as Prisma.UserUpdateInput }),
51
- deleteUser: (id) => db.user.delete({ where: { id } }),
52
- linkAccount: (data) => db.account.create({ data }) as any,
53
- unlinkAccount: (provider_providerAccountId) =>
54
- db.account.delete({ where: { provider_providerAccountId } }) as any,
55
- async getSessionAndUser(sessionToken) {
56
- const userAndSession = await db.session.findUnique({
57
- where: { sessionToken },
58
- include: { user: true },
59
- });
60
- if (!userAndSession) return null;
61
- const { user, ...session } = userAndSession;
62
- return { user, session };
63
- },
64
- createSession: (data) => db.session.create({ data }),
65
- updateSession: (data) =>
66
- db.session.update({
67
- data,
68
- where: { sessionToken: data.sessionToken },
69
- }),
70
- deleteSession: (sessionToken) =>
71
- db.session.delete({ where: { sessionToken } }),
72
- createVerificationToken: (data) => db.verificationToken.create({ data }),
73
- async useVerificationToken(identifier_token) {
74
- try {
75
- return await db.verificationToken.delete({
76
- where: { identifier_token },
77
- });
78
- } catch (error) {
79
- // If token already used/deleted, just return null
80
- // https://www.prisma.io/docs/reference/api-reference/error-reference#p2025
81
- if (
82
- (error as Prisma.PrismaClientKnownRequestError).code ===
83
- 'P2025'
84
- )
85
- return null;
86
- throw error;
87
- }
88
- },
89
- };
90
- }
91
- `;
92
-
93
- const sf = project.createSourceFile(
94
- path.join(context.outDir, 'auth/next-auth-adapter.ts'),
95
- content,
96
- { overwrite: true }
97
- );
98
-
99
- sf.formatText();
100
- }
101
-
102
- generateAuthorize(project: Project, context: Context) {
103
- const content = `
104
- import { ZenStackService } from '..';
105
- import { hash, compare } from 'bcryptjs';
106
-
107
- async function hashPassword(password: string) {
108
- const hashedPassword = await hash(password, 12);
109
- return hashedPassword;
110
- }
111
-
112
- async function verifyPassword(password: string, hashedPassword: string) {
113
- const isValid = await compare(password, hashedPassword);
114
- return isValid;
115
- }
116
-
117
- export function authorize(service: ZenStackService) {
118
- return async (
119
- credentials: Record<'email' | 'password', string> | undefined
120
- ) => {
121
- try {
122
- let maybeUser = await service.db.user.findFirst({
123
- where: {
124
- email: credentials!.email,
125
- },
126
- select: {
127
- id: true,
128
- email: true,
129
- password: true,
130
- name: true,
131
- },
132
- });
133
-
134
- if (!maybeUser) {
135
- if (!credentials!.password || !credentials!.email) {
136
- throw new Error('Invalid Credentials');
137
- }
138
-
139
- maybeUser = await service.db.user.create({
140
- data: {
141
- email: credentials!.email,
142
- password: await hashPassword(credentials!.password),
143
- },
144
- select: {
145
- id: true,
146
- email: true,
147
- password: true,
148
- name: true,
149
- },
150
- });
151
- } else {
152
- const isValid = await verifyPassword(
153
- credentials!.password,
154
- maybeUser.password
155
- );
156
-
157
- if (!isValid) {
158
- throw new Error('Invalid Credentials');
159
- }
160
- }
161
-
162
- return {
163
- id: maybeUser.id,
164
- email: maybeUser.email,
165
- name: maybeUser.name,
166
- };
167
- } catch (error) {
168
- console.log(error);
169
- throw error;
170
- }
171
- };
172
- }
173
- `;
174
-
175
- const sf = project.createSourceFile(
176
- path.join(context.outDir, 'auth/authorize.ts'),
177
- content,
178
- { overwrite: true }
179
- );
180
-
181
- sf.formatText();
182
- }
183
- }
@@ -1,9 +0,0 @@
1
- {
2
- "name": ".zenstack",
3
- "version": "1.0.0",
4
- "description": "ZenStack generated code",
5
- "main": "index.js",
6
- "types": "index.d.ts",
7
- "author": "ZenStack",
8
- "license": "MIT"
9
- }