Skip to content

Commit 15cee92

Browse files
authored
feat: make good progress on the Todo demo (#5)
* WIP * Progress * wip
1 parent b8dbed4 commit 15cee92

39 files changed

+1297
-440
lines changed

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
"version": "1.0.0",
44
"description": "",
55
"main": "index.js",
6-
"scripts": {},
6+
"scripts": {
7+
"build": "pnpm -r build",
8+
"test": "pnpm -r test"
9+
},
710
"keywords": [],
811
"author": "",
912
"license": "ISC"

packages/internal/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zenstackhq/internal",
3-
"version": "0.1.6",
3+
"version": "0.1.18",
44
"description": "ZenStack internal runtime library",
55
"main": "lib/index.js",
66
"types": "lib/index.d.ts",

packages/internal/src/handler/data/handler.ts

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { QueryProcessor } from './query-processor';
1212
const PRISMA_ERROR_MAPPING: Record<string, ServerErrorCode> = {
1313
P2002: ServerErrorCode.UNIQUE_CONSTRAINT_VIOLATION,
1414
P2003: ServerErrorCode.REFERENCE_CONSTRAINT_VIOLATION,
15+
P2025: ServerErrorCode.REFERENCE_CONSTRAINT_VIOLATION,
1516
};
1617

1718
export default class DataHandler<DbClient> implements RequestHandler {
@@ -125,9 +126,7 @@ export default class DataHandler<DbClient> implements RequestHandler {
125126
r = await db.findMany(processedArgs);
126127
}
127128

128-
console.log(
129-
`Finding ${model}:\n${JSON.stringify(processedArgs, undefined, 2)}`
130-
);
129+
console.log(`Finding ${model}:\n${JSON.stringify(processedArgs)}`);
131130
await this.queryProcessor.postProcess(
132131
model,
133132
processedArgs,
@@ -163,13 +162,7 @@ export default class DataHandler<DbClient> implements RequestHandler {
163162
);
164163

165164
const r = await db.$transaction(async (tx: any) => {
166-
console.log(
167-
`Create ${model}:\n${JSON.stringify(
168-
processedArgs,
169-
undefined,
170-
2
171-
)}`
172-
);
165+
console.log(`Create ${model}:\n${JSON.stringify(processedArgs)}`);
173166
const created = await tx[model].create(processedArgs);
174167

175168
let queryArgs = {
@@ -184,11 +177,7 @@ export default class DataHandler<DbClient> implements RequestHandler {
184177
context
185178
);
186179
console.log(
187-
`Finding created ${model}:\n${JSON.stringify(
188-
queryArgs,
189-
undefined,
190-
2
191-
)}`
180+
`Finding created ${model}:\n${JSON.stringify(queryArgs)}`
192181
);
193182
const found = await tx[model].findFirst(queryArgs);
194183
if (!found) {
@@ -247,9 +236,7 @@ export default class DataHandler<DbClient> implements RequestHandler {
247236
updateArgs.where = { ...updateArgs.where, id };
248237

249238
const r = await db.$transaction(async (tx: any) => {
250-
console.log(
251-
`Update ${model}:\n${JSON.stringify(updateArgs, undefined, 2)}`
252-
);
239+
console.log(`Update ${model}:\n${JSON.stringify(updateArgs)}`);
253240
const updated = await tx[model].update(updateArgs);
254241

255242
// make sure after update, the entity passes policy check
@@ -265,11 +252,7 @@ export default class DataHandler<DbClient> implements RequestHandler {
265252
context
266253
);
267254
console.log(
268-
`Finding post-updated ${model}:\n${JSON.stringify(
269-
queryArgs,
270-
undefined,
271-
2
272-
)}`
255+
`Finding post-updated ${model}:\n${JSON.stringify(queryArgs)}`
273256
);
274257
const found = await tx[model].findFirst(queryArgs);
275258
if (!found) {
@@ -321,9 +304,7 @@ export default class DataHandler<DbClient> implements RequestHandler {
321304
);
322305
delArgs.where = { ...delArgs.where, id };
323306

324-
console.log(
325-
`Deleting ${model}:\n${JSON.stringify(delArgs, undefined, 2)}`
326-
);
307+
console.log(`Deleting ${model}:\n${JSON.stringify(delArgs)}`);
327308
const db = (this.service.db as any)[model];
328309
const r = await db.delete(delArgs);
329310
await this.queryProcessor.postProcess(
@@ -353,11 +334,7 @@ export default class DataHandler<DbClient> implements RequestHandler {
353334
context
354335
);
355336
console.log(
356-
`Finding to-be-deleted ${model}:\n${JSON.stringify(
357-
readArgs,
358-
undefined,
359-
2
360-
)}`
337+
`Finding to-be-deleted ${model}:\n${JSON.stringify(readArgs)}`
361338
);
362339
const read = await db.findFirst(readArgs);
363340
if (!read) {

packages/internal/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from './types';
22
export * from './request-handler';
3+
export * as request from './request';

packages/internal/src/request.ts

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import useSWR, { useSWRConfig } from 'swr';
2-
import type { ScopedMutator } from 'swr/dist/types';
2+
import type { MutatorCallback, MutatorOptions } from 'swr/dist/types';
33

44
const fetcher = async (url: string, options?: RequestInit) => {
55
const res = await fetch(url, options);
@@ -15,17 +15,17 @@ const fetcher = async (url: string, options?: RequestInit) => {
1515
};
1616

1717
function makeUrl(url: string, args: unknown) {
18-
return args ? url + `q=${encodeURIComponent(JSON.stringify(args))}` : url;
18+
return args ? url + `?q=${encodeURIComponent(JSON.stringify(args))}` : url;
1919
}
2020

21-
export function get<Data, Error = any>(url: string, args?: unknown) {
22-
return useSWR<Data, Error>(makeUrl(url, args), fetcher);
21+
export function get<Data, Error = any>(url: string | null, args?: unknown) {
22+
return useSWR<Data, Error>(url && makeUrl(url, args), fetcher);
2323
}
2424

2525
export async function post<Data, Result>(
2626
url: string,
2727
data: Data,
28-
mutate: ScopedMutator<any>
28+
mutate: Mutator
2929
) {
3030
const r: Result = await fetcher(url, {
3131
method: 'POST',
@@ -34,14 +34,14 @@ export async function post<Data, Result>(
3434
},
3535
body: JSON.stringify(data),
3636
});
37-
mutate(url);
37+
mutate(url, true);
3838
return r;
3939
}
4040

4141
export async function put<Data, Result>(
4242
url: string,
4343
data: Data,
44-
mutate: ScopedMutator<any>
44+
mutate: Mutator
4545
) {
4646
const r: Result = await fetcher(url, {
4747
method: 'PUT',
@@ -50,26 +50,52 @@ export async function put<Data, Result>(
5050
},
5151
body: JSON.stringify(data),
5252
});
53-
mutate(url, r);
53+
mutate(url, true);
5454
return r;
5555
}
5656

57-
export async function del<Result>(
58-
url: string,
59-
args: unknown,
60-
mutate: ScopedMutator<any>
61-
) {
57+
export async function del<Result>(url: string, args: unknown, mutate: Mutator) {
6258
const reqUrl = makeUrl(url, args);
6359
const r: Result = await fetcher(reqUrl, {
6460
method: 'DELETE',
6561
});
6662
const path = url.split('/');
6763
path.pop();
68-
mutate(path.join('/'));
64+
mutate(path.join('/'), true);
6965
return r;
7066
}
7167

72-
export function getMutate() {
73-
const { mutate } = useSWRConfig();
74-
return mutate;
68+
type Mutator = (
69+
key: string,
70+
prefix: boolean,
71+
data?: any | Promise<any> | MutatorCallback,
72+
opts?: boolean | MutatorOptions
73+
) => Promise<any[]>;
74+
75+
export function getMutate(): Mutator {
76+
// https://swr.vercel.app/docs/advanced/cache#mutate-multiple-keys-from-regex
77+
const { cache, mutate } = useSWRConfig();
78+
return (
79+
key: string,
80+
prefix: boolean,
81+
data?: any | Promise<any> | MutatorCallback,
82+
opts?: boolean | MutatorOptions
83+
) => {
84+
if (!prefix) {
85+
return mutate(key, data, opts);
86+
}
87+
88+
if (!(cache instanceof Map)) {
89+
throw new Error(
90+
'mutate requires the cache provider to be a Map instance'
91+
);
92+
}
93+
94+
const keys = Array.from(cache.keys()).filter(
95+
(k) => typeof k === 'string' && k.startsWith(key)
96+
) as string[];
97+
console.log('Mutating keys:', JSON.stringify(keys));
98+
const mutations = keys.map((key) => mutate(key, data, opts));
99+
return Promise.all(mutations);
100+
};
75101
}

packages/internal/src/request/index.ts

Lines changed: 0 additions & 75 deletions
This file was deleted.

packages/runtime/hooks.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,10 @@
1+
import { ServerErrorCode } from '@zenstackhq/internal';
2+
13
export * from '.zenstack/lib/hooks';
4+
export type HooksError = {
5+
status: number;
6+
info: {
7+
code: ServerErrorCode;
8+
message: string;
9+
};
10+
};

packages/runtime/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zenstackhq/runtime",
3-
"version": "0.1.17",
3+
"version": "0.1.18",
44
"description": "ZenStack generated runtime code",
55
"main": "index.js",
66
"types": "index.d.ts",

packages/schema/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "zenstack",
33
"displayName": "ZenStack CLI and Language Tools",
44
"description": "ZenStack CLI and Language Tools",
5-
"version": "0.1.22",
5+
"version": "0.1.32",
66
"engines": {
77
"vscode": "^1.56.0"
88
},

packages/schema/src/generator/next-auth/index.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Context, Generator } from '../types';
22
import { Project } from 'ts-morph';
33
import * as path from 'path';
4+
import colors from 'colors';
45

56
export default class NextAuthGenerator implements Generator {
67
async generate(context: Context) {
@@ -11,6 +12,8 @@ export default class NextAuthGenerator implements Generator {
1112
this.generateAuthorize(project, context);
1213

1314
await project.save();
15+
16+
console.log(colors.blue(` ✔️ Next-auth adapter generated`));
1417
}
1518

1619
generateIndex(project: Project, context: Context) {
@@ -118,6 +121,10 @@ export default class NextAuthGenerator implements Generator {
118121
return async (
119122
credentials: Record<'email' | 'password', string> | undefined
120123
) => {
124+
if (!credentials) {
125+
throw new Error('Missing credentials');
126+
}
127+
121128
try {
122129
let maybeUser = await service.db.user.findFirst({
123130
where: {
@@ -132,14 +139,14 @@ export default class NextAuthGenerator implements Generator {
132139
});
133140
134141
if (!maybeUser) {
135-
if (!credentials!.password || !credentials!.email) {
142+
if (!credentials.password || !credentials.email) {
136143
throw new Error('Invalid Credentials');
137144
}
138145
139146
maybeUser = await service.db.user.create({
140147
data: {
141-
email: credentials!.email,
142-
password: await hashPassword(credentials!.password),
148+
email: credentials.email,
149+
password: await hashPassword(credentials.password),
143150
},
144151
select: {
145152
id: true,
@@ -149,8 +156,12 @@ export default class NextAuthGenerator implements Generator {
149156
},
150157
});
151158
} else {
159+
if (!maybeUser.password) {
160+
throw new Error('Invalid User Record');
161+
}
162+
152163
const isValid = await verifyPassword(
153-
credentials!.password,
164+
credentials.password,
154165
maybeUser.password
155166
);
156167

0 commit comments

Comments
 (0)