@fitzzero/quickdraw-core 3.6.0 → 3.7.0
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 +113 -64
- package/dist/client/index.js +32 -61
- package/dist/client/index.js.map +1 -1
- package/dist/client/testing.js.map +1 -1
- package/dist/server/express/index.d.ts +37 -0
- package/dist/server/express/index.js +60 -0
- package/dist/server/express/index.js.map +1 -0
- package/dist/server/index.d.ts +227 -1
- package/dist/server/index.js +400 -142
- package/dist/server/index.js.map +1 -1
- package/dist/server/testing-prisma.d.ts +101 -0
- package/dist/server/testing-prisma.js +172 -0
- package/dist/server/testing-prisma.js.map +1 -0
- package/dist/server/testing.js +5 -22
- package/dist/server/testing.js.map +1 -1
- package/dist/shared/index.js.map +1 -1
- package/eslint-config/index.mjs +1 -2
- package/eslint-plugin-quickdraw/index.mjs +15 -7
- package/eslint-plugin-quickdraw/rules/no-cross-service-mutations.mjs +31 -32
- package/eslint-plugin-quickdraw/rules/no-direct-prisma-mutations.mjs +17 -18
- package/eslint-plugin-quickdraw/rules/no-raw-button-strings.mjs +52 -0
- package/eslint-plugin-quickdraw/rules/no-raw-service-room-string.mjs +140 -0
- package/eslint-plugin-quickdraw/rules/no-raw-socket-emit.mjs +20 -22
- package/eslint-plugin-quickdraw/rules/no-raw-socket-on.mjs +17 -17
- package/eslint-plugin-quickdraw/rules/no-raw-tooltip-strings.mjs +59 -0
- package/eslint-plugin-quickdraw/rules/no-raw-typography-strings.mjs +52 -0
- package/eslint-plugin-quickdraw/rules/no-service-method-record.mjs +3 -3
- package/eslint-plugin-quickdraw/rules/no-unsafe-payload-cast.mjs +8 -8
- package/eslint-plugin-quickdraw/rules/require-zod-schema.mjs +15 -20
- package/package.json +74 -50
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** @type {import('eslint').Rule.RuleModule} */
|
|
2
|
+
export default {
|
|
3
|
+
meta: {
|
|
4
|
+
type: "problem",
|
|
5
|
+
docs: {
|
|
6
|
+
description:
|
|
7
|
+
"Disallow raw string literals in Typography components. Use useTranslations() or the <T> component for localization.",
|
|
8
|
+
},
|
|
9
|
+
messages: {
|
|
10
|
+
noRawTypographyStrings:
|
|
11
|
+
"Raw string '{{content}}' in Typography component should be localized. Use t('key') or <T>key</T> instead.",
|
|
12
|
+
},
|
|
13
|
+
schema: [],
|
|
14
|
+
},
|
|
15
|
+
create(context) {
|
|
16
|
+
return {
|
|
17
|
+
JSXElement(node) {
|
|
18
|
+
// Check if this is a Typography element
|
|
19
|
+
if (
|
|
20
|
+
node.openingElement.name.type !== "JSXIdentifier" ||
|
|
21
|
+
node.openingElement.name.name !== "Typography"
|
|
22
|
+
) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Check all children for raw strings
|
|
27
|
+
for (const child of node.children) {
|
|
28
|
+
if (child.type === "JSXText") {
|
|
29
|
+
// Flag JSXText that contains non-whitespace characters
|
|
30
|
+
const trimmedText = child.value.trim();
|
|
31
|
+
if (trimmedText.length > 0) {
|
|
32
|
+
context.report({
|
|
33
|
+
node: child,
|
|
34
|
+
messageId: "noRawTypographyStrings",
|
|
35
|
+
data: { content: trimmedText },
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
} else if (child.type === "JSXExpressionContainer") {
|
|
39
|
+
// Flag JSXExpressionContainer where the expression is a string literal
|
|
40
|
+
if (child.expression.type === "Literal" && typeof child.expression.value === "string") {
|
|
41
|
+
context.report({
|
|
42
|
+
node: child,
|
|
43
|
+
messageId: "noRawTypographyStrings",
|
|
44
|
+
data: { content: child.expression.value },
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -17,12 +17,12 @@ export default {
|
|
|
17
17
|
create(context) {
|
|
18
18
|
return {
|
|
19
19
|
TSAsExpression(node) {
|
|
20
|
-
const typeAnnotation = node.typeAnnotation
|
|
21
|
-
if (typeAnnotation.type !== "TSTypeReference") return
|
|
22
|
-
if (typeAnnotation.typeName?.type !== "TSQualifiedName") return
|
|
20
|
+
const typeAnnotation = node.typeAnnotation;
|
|
21
|
+
if (typeAnnotation.type !== "TSTypeReference") return;
|
|
22
|
+
if (typeAnnotation.typeName?.type !== "TSQualifiedName") return;
|
|
23
23
|
|
|
24
|
-
const left = typeAnnotation.typeName.left
|
|
25
|
-
const right = typeAnnotation.typeName.right
|
|
24
|
+
const left = typeAnnotation.typeName.left;
|
|
25
|
+
const right = typeAnnotation.typeName.right;
|
|
26
26
|
|
|
27
27
|
if (
|
|
28
28
|
left.type === "Identifier" &&
|
|
@@ -33,9 +33,9 @@ export default {
|
|
|
33
33
|
context.report({
|
|
34
34
|
node,
|
|
35
35
|
messageId: "noUnsafePayloadCast",
|
|
36
|
-
})
|
|
36
|
+
});
|
|
37
37
|
}
|
|
38
38
|
},
|
|
39
|
-
}
|
|
39
|
+
};
|
|
40
40
|
},
|
|
41
|
-
}
|
|
41
|
+
};
|
|
@@ -16,45 +16,40 @@ export default {
|
|
|
16
16
|
create(context) {
|
|
17
17
|
return {
|
|
18
18
|
CallExpression(node) {
|
|
19
|
-
const callee = node.callee
|
|
20
|
-
if (callee.type !== "MemberExpression") return
|
|
21
|
-
if (callee.property.type !== "Identifier") return
|
|
22
|
-
if (callee.property.name !== "defineMethod") return
|
|
23
|
-
if (callee.object.type !== "ThisExpression") return
|
|
19
|
+
const callee = node.callee;
|
|
20
|
+
if (callee.type !== "MemberExpression") return;
|
|
21
|
+
if (callee.property.type !== "Identifier") return;
|
|
22
|
+
if (callee.property.name !== "defineMethod") return;
|
|
23
|
+
if (callee.object.type !== "ThisExpression") return;
|
|
24
24
|
|
|
25
|
-
const methodNameArg = node.arguments[0]
|
|
25
|
+
const methodNameArg = node.arguments[0];
|
|
26
26
|
const methodName =
|
|
27
|
-
methodNameArg?.type === "Literal"
|
|
28
|
-
? String(methodNameArg.value)
|
|
29
|
-
: "unknown"
|
|
27
|
+
methodNameArg?.type === "Literal" ? String(methodNameArg.value) : "unknown";
|
|
30
28
|
|
|
31
|
-
const optionsArg = node.arguments[3]
|
|
29
|
+
const optionsArg = node.arguments[3];
|
|
32
30
|
|
|
33
31
|
if (!optionsArg) {
|
|
34
32
|
context.report({
|
|
35
33
|
node,
|
|
36
34
|
messageId: "missingSchema",
|
|
37
35
|
data: { methodName },
|
|
38
|
-
})
|
|
39
|
-
return
|
|
36
|
+
});
|
|
37
|
+
return;
|
|
40
38
|
}
|
|
41
39
|
|
|
42
40
|
if (optionsArg.type === "ObjectExpression") {
|
|
43
41
|
const hasSchema = optionsArg.properties.some(
|
|
44
|
-
(p) =>
|
|
45
|
-
|
|
46
|
-
p.key.type === "Identifier" &&
|
|
47
|
-
p.key.name === "schema"
|
|
48
|
-
)
|
|
42
|
+
(p) => p.type === "Property" && p.key.type === "Identifier" && p.key.name === "schema",
|
|
43
|
+
);
|
|
49
44
|
if (!hasSchema) {
|
|
50
45
|
context.report({
|
|
51
46
|
node,
|
|
52
47
|
messageId: "missingSchema",
|
|
53
48
|
data: { methodName },
|
|
54
|
-
})
|
|
49
|
+
});
|
|
55
50
|
}
|
|
56
51
|
}
|
|
57
52
|
},
|
|
58
|
-
}
|
|
53
|
+
};
|
|
59
54
|
},
|
|
60
|
-
}
|
|
55
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fitzzero/quickdraw-core",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.7.0",
|
|
4
4
|
"description": "Fast fullstack patterns for real-time applications with Socket.io and TanStack Query",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"fullstack",
|
|
7
|
+
"react",
|
|
8
|
+
"real-time",
|
|
9
|
+
"socket.io",
|
|
10
|
+
"tanstack-query",
|
|
11
|
+
"typescript"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"author": "",
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"eslint-plugin-quickdraw",
|
|
18
|
+
"eslint-config"
|
|
19
|
+
],
|
|
5
20
|
"type": "module",
|
|
6
21
|
"main": "./dist/shared/index.js",
|
|
7
22
|
"module": "./dist/shared/index.js",
|
|
@@ -23,6 +38,14 @@
|
|
|
23
38
|
"import": "./dist/server/testing.js",
|
|
24
39
|
"types": "./dist/server/testing.d.ts"
|
|
25
40
|
},
|
|
41
|
+
"./server/testing/prisma": {
|
|
42
|
+
"import": "./dist/server/testing-prisma.js",
|
|
43
|
+
"types": "./dist/server/testing-prisma.d.ts"
|
|
44
|
+
},
|
|
45
|
+
"./server/express": {
|
|
46
|
+
"import": "./dist/server/express/index.js",
|
|
47
|
+
"types": "./dist/server/express/index.d.ts"
|
|
48
|
+
},
|
|
26
49
|
"./client/testing": {
|
|
27
50
|
"import": "./dist/client/testing.js",
|
|
28
51
|
"types": "./dist/client/testing.d.ts"
|
|
@@ -34,11 +57,9 @@
|
|
|
34
57
|
"import": "./eslint-config/index.mjs"
|
|
35
58
|
}
|
|
36
59
|
},
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
"eslint-config"
|
|
41
|
-
],
|
|
60
|
+
"publishConfig": {
|
|
61
|
+
"access": "public"
|
|
62
|
+
},
|
|
42
63
|
"scripts": {
|
|
43
64
|
"build": "tsup",
|
|
44
65
|
"dev": "tsup --watch",
|
|
@@ -52,29 +73,61 @@
|
|
|
52
73
|
"test:coverage": "vitest run --coverage",
|
|
53
74
|
"prepublishOnly": "bun run build"
|
|
54
75
|
},
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
76
|
+
"dependencies": {
|
|
77
|
+
"jose": "^5.2.0",
|
|
78
|
+
"zod": "^3.22.0"
|
|
79
|
+
},
|
|
80
|
+
"devDependencies": {
|
|
81
|
+
"@electric-sql/pglite": "^0.3.16",
|
|
82
|
+
"@prisma/client": "^5.10.0",
|
|
83
|
+
"@tanstack/react-query": "^5.20.0",
|
|
84
|
+
"@testing-library/react": "^14.2.0",
|
|
85
|
+
"@types/express": "^4.17.21",
|
|
86
|
+
"@types/node": "^20.11.0",
|
|
87
|
+
"@types/pg": "^8.11.0",
|
|
88
|
+
"@types/react": "^18.2.0",
|
|
89
|
+
"@typescript/native-preview": "^7.0.0-dev",
|
|
90
|
+
"@vitest/coverage-v8": "^1.3.0",
|
|
91
|
+
"express": "^4.18.2",
|
|
92
|
+
"express-rate-limit": "^8.3.1",
|
|
93
|
+
"jsdom": "^24.0.0",
|
|
94
|
+
"oxfmt": "^0.37.0",
|
|
95
|
+
"oxlint": "^1.52.0",
|
|
96
|
+
"pg": "^8.13.0",
|
|
97
|
+
"react": "^18.2.0",
|
|
98
|
+
"react-dom": "^18.2.0",
|
|
99
|
+
"socket.io": "^4.7.4",
|
|
100
|
+
"socket.io-client": "^4.7.4",
|
|
101
|
+
"tsup": "^8.0.2",
|
|
102
|
+
"typescript": "^5.3.3",
|
|
103
|
+
"vitest": "^1.3.0",
|
|
104
|
+
"winston": "^3.11.0"
|
|
105
|
+
},
|
|
65
106
|
"peerDependencies": {
|
|
107
|
+
"@electric-sql/pglite": ">=0.3.0",
|
|
108
|
+
"@eslint/js": ">=9.0.0",
|
|
66
109
|
"@prisma/client": ">=5.0.0",
|
|
67
110
|
"@tanstack/react-query": ">=5.0.0",
|
|
111
|
+
"eslint": ">=9.0.0",
|
|
112
|
+
"eslint-config-next": ">=16.0.0",
|
|
113
|
+
"express-rate-limit": ">=8.0.0",
|
|
114
|
+
"globals": ">=16.0.0",
|
|
115
|
+
"pg": ">=8.0.0",
|
|
68
116
|
"react": ">=18.0.0",
|
|
69
117
|
"socket.io": ">=4.0.0",
|
|
70
118
|
"socket.io-client": ">=4.0.0",
|
|
71
|
-
"eslint": ">=
|
|
72
|
-
"@eslint/js": ">=9.0.0",
|
|
73
|
-
"typescript-eslint": ">=8.0.0",
|
|
74
|
-
"globals": ">=16.0.0",
|
|
75
|
-
"eslint-config-next": ">=16.0.0"
|
|
119
|
+
"typescript-eslint": ">=8.0.0"
|
|
76
120
|
},
|
|
77
121
|
"peerDependenciesMeta": {
|
|
122
|
+
"@electric-sql/pglite": {
|
|
123
|
+
"optional": true
|
|
124
|
+
},
|
|
125
|
+
"express-rate-limit": {
|
|
126
|
+
"optional": true
|
|
127
|
+
},
|
|
128
|
+
"pg": {
|
|
129
|
+
"optional": true
|
|
130
|
+
},
|
|
78
131
|
"@prisma/client": {
|
|
79
132
|
"optional": true
|
|
80
133
|
},
|
|
@@ -106,35 +159,6 @@
|
|
|
106
159
|
"optional": true
|
|
107
160
|
}
|
|
108
161
|
},
|
|
109
|
-
"dependencies": {
|
|
110
|
-
"jose": "^5.2.0",
|
|
111
|
-
"zod": "^3.22.0"
|
|
112
|
-
},
|
|
113
|
-
"devDependencies": {
|
|
114
|
-
"@prisma/client": "^5.10.0",
|
|
115
|
-
"@tanstack/react-query": "^5.20.0",
|
|
116
|
-
"@testing-library/react": "^14.2.0",
|
|
117
|
-
"@types/express": "^4.17.21",
|
|
118
|
-
"@types/node": "^20.11.0",
|
|
119
|
-
"@types/react": "^18.2.0",
|
|
120
|
-
"@typescript/native-preview": "^7.0.0-dev",
|
|
121
|
-
"@vitest/coverage-v8": "^1.3.0",
|
|
122
|
-
"express": "^4.18.2",
|
|
123
|
-
"jsdom": "^24.0.0",
|
|
124
|
-
"oxfmt": "^0.37.0",
|
|
125
|
-
"oxlint": "^1.52.0",
|
|
126
|
-
"react": "^18.2.0",
|
|
127
|
-
"react-dom": "^18.2.0",
|
|
128
|
-
"socket.io": "^4.7.4",
|
|
129
|
-
"socket.io-client": "^4.7.4",
|
|
130
|
-
"tsup": "^8.0.2",
|
|
131
|
-
"typescript": "^5.3.3",
|
|
132
|
-
"vitest": "^1.3.0",
|
|
133
|
-
"winston": "^3.11.0"
|
|
134
|
-
},
|
|
135
|
-
"publishConfig": {
|
|
136
|
-
"access": "public"
|
|
137
|
-
},
|
|
138
162
|
"engines": {
|
|
139
163
|
"node": ">=20"
|
|
140
164
|
}
|