zitejs 0.9.120 → 0.9.121
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/cjs/auth/config.d.ts +3 -0
- package/dist/cjs/auth/config.js +7 -0
- package/dist/cjs/auth/index.js +30 -4
- package/dist/cjs/auth/useAuth.test.js +5 -19
- package/dist/cjs/backend/index.d.ts +30 -3
- package/dist/cjs/backend/index.js +2 -2
- package/dist/cjs/bundle/index.d.ts +1 -1
- package/dist/cjs/bundle/index.js +6 -2
- package/dist/cjs/check/index.js +5 -13
- package/dist/cjs/cli.js +2 -2
- package/dist/cjs/dev/index.js +22 -29
- package/dist/cjs/sourceRoots.d.ts +19 -0
- package/dist/cjs/sourceRoots.js +33 -0
- package/dist/cjs/upload/index.js +19 -0
- package/dist/cjs/upload/index.test.js +30 -3
- package/dist/cjs/vite/domTagNames.d.ts +1 -0
- package/dist/cjs/vite/domTagNames.js +257 -0
- package/dist/cjs/vite/index.js +20 -11
- package/dist/cjs/vite/index.test.d.ts +1 -0
- package/dist/cjs/vite/index.test.js +53 -0
- package/dist/esm/auth/config.d.ts +3 -0
- package/dist/esm/auth/config.js +6 -0
- package/dist/esm/auth/index.js +28 -2
- package/dist/esm/auth/useAuth.test.js +5 -19
- package/dist/esm/backend/index.d.ts +30 -3
- package/dist/esm/backend/index.js +2 -2
- package/dist/esm/bundle/index.d.ts +1 -1
- package/dist/esm/bundle/index.js +6 -2
- package/dist/esm/check/index.js +6 -14
- package/dist/esm/cli.js +2 -2
- package/dist/esm/dev/index.js +22 -29
- package/dist/esm/sourceRoots.d.ts +19 -0
- package/dist/esm/sourceRoots.js +28 -0
- package/dist/esm/upload/index.js +19 -0
- package/dist/esm/upload/index.test.js +30 -3
- package/dist/esm/vite/domTagNames.d.ts +1 -0
- package/dist/esm/vite/domTagNames.js +254 -0
- package/dist/esm/vite/index.js +20 -11
- package/dist/esm/vite/index.test.d.ts +1 -0
- package/dist/esm/vite/index.test.js +48 -0
- package/package.json +1 -1
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.domTagNames = void 0;
|
|
4
|
+
exports.domTagNames = new Set([
|
|
5
|
+
"a",
|
|
6
|
+
"abbr",
|
|
7
|
+
"acronym",
|
|
8
|
+
"address",
|
|
9
|
+
"altGlyph",
|
|
10
|
+
"altGlyphDef",
|
|
11
|
+
"altGlyphItem",
|
|
12
|
+
"animate",
|
|
13
|
+
"animateColor",
|
|
14
|
+
"animateMotion",
|
|
15
|
+
"animateTransform",
|
|
16
|
+
"annotation",
|
|
17
|
+
"annotation-xml",
|
|
18
|
+
"applet",
|
|
19
|
+
"area",
|
|
20
|
+
"article",
|
|
21
|
+
"aside",
|
|
22
|
+
"audio",
|
|
23
|
+
"b",
|
|
24
|
+
"base",
|
|
25
|
+
"basefont",
|
|
26
|
+
"bdi",
|
|
27
|
+
"bdo",
|
|
28
|
+
"bgsound",
|
|
29
|
+
"big",
|
|
30
|
+
"blink",
|
|
31
|
+
"blockquote",
|
|
32
|
+
"body",
|
|
33
|
+
"br",
|
|
34
|
+
"button",
|
|
35
|
+
"canvas",
|
|
36
|
+
"caption",
|
|
37
|
+
"center",
|
|
38
|
+
"circle",
|
|
39
|
+
"cite",
|
|
40
|
+
"clipPath",
|
|
41
|
+
"code",
|
|
42
|
+
"col",
|
|
43
|
+
"colgroup",
|
|
44
|
+
"color-profile",
|
|
45
|
+
"command",
|
|
46
|
+
"content",
|
|
47
|
+
"cursor",
|
|
48
|
+
"data",
|
|
49
|
+
"datalist",
|
|
50
|
+
"dd",
|
|
51
|
+
"defs",
|
|
52
|
+
"del",
|
|
53
|
+
"desc",
|
|
54
|
+
"details",
|
|
55
|
+
"dfn",
|
|
56
|
+
"dialog",
|
|
57
|
+
"dir",
|
|
58
|
+
"discard",
|
|
59
|
+
"div",
|
|
60
|
+
"dl",
|
|
61
|
+
"dt",
|
|
62
|
+
"ellipse",
|
|
63
|
+
"em",
|
|
64
|
+
"embed",
|
|
65
|
+
"feBlend",
|
|
66
|
+
"feColorMatrix",
|
|
67
|
+
"feComponentTransfer",
|
|
68
|
+
"feComposite",
|
|
69
|
+
"feConvolveMatrix",
|
|
70
|
+
"feDiffuseLighting",
|
|
71
|
+
"feDisplacementMap",
|
|
72
|
+
"feDistantLight",
|
|
73
|
+
"feDropShadow",
|
|
74
|
+
"feFlood",
|
|
75
|
+
"feFuncA",
|
|
76
|
+
"feFuncB",
|
|
77
|
+
"feFuncG",
|
|
78
|
+
"feFuncR",
|
|
79
|
+
"feGaussianBlur",
|
|
80
|
+
"feImage",
|
|
81
|
+
"feMerge",
|
|
82
|
+
"feMergeNode",
|
|
83
|
+
"feMorphology",
|
|
84
|
+
"feOffset",
|
|
85
|
+
"fePointLight",
|
|
86
|
+
"feSpecularLighting",
|
|
87
|
+
"feSpotLight",
|
|
88
|
+
"feTile",
|
|
89
|
+
"feTurbulence",
|
|
90
|
+
"fieldset",
|
|
91
|
+
"figcaption",
|
|
92
|
+
"figure",
|
|
93
|
+
"filter",
|
|
94
|
+
"font",
|
|
95
|
+
"font-face",
|
|
96
|
+
"font-face-format",
|
|
97
|
+
"font-face-name",
|
|
98
|
+
"font-face-src",
|
|
99
|
+
"font-face-uri",
|
|
100
|
+
"footer",
|
|
101
|
+
"foreignObject",
|
|
102
|
+
"form",
|
|
103
|
+
"frame",
|
|
104
|
+
"frameset",
|
|
105
|
+
"g",
|
|
106
|
+
"glyph",
|
|
107
|
+
"glyphRef",
|
|
108
|
+
"h1",
|
|
109
|
+
"h2",
|
|
110
|
+
"h3",
|
|
111
|
+
"h4",
|
|
112
|
+
"h5",
|
|
113
|
+
"h6",
|
|
114
|
+
"head",
|
|
115
|
+
"header",
|
|
116
|
+
"hgroup",
|
|
117
|
+
"hkern",
|
|
118
|
+
"hr",
|
|
119
|
+
"html",
|
|
120
|
+
"i",
|
|
121
|
+
"iframe",
|
|
122
|
+
"image",
|
|
123
|
+
"img",
|
|
124
|
+
"input",
|
|
125
|
+
"ins",
|
|
126
|
+
"isindex",
|
|
127
|
+
"kbd",
|
|
128
|
+
"keygen",
|
|
129
|
+
"label",
|
|
130
|
+
"legend",
|
|
131
|
+
"li",
|
|
132
|
+
"line",
|
|
133
|
+
"linearGradient",
|
|
134
|
+
"link",
|
|
135
|
+
"listing",
|
|
136
|
+
"maction",
|
|
137
|
+
"main",
|
|
138
|
+
"map",
|
|
139
|
+
"mark",
|
|
140
|
+
"marker",
|
|
141
|
+
"marquee",
|
|
142
|
+
"mask",
|
|
143
|
+
"math",
|
|
144
|
+
"menu",
|
|
145
|
+
"menuitem",
|
|
146
|
+
"merror",
|
|
147
|
+
"meta",
|
|
148
|
+
"metadata",
|
|
149
|
+
"meter",
|
|
150
|
+
"mfrac",
|
|
151
|
+
"mi",
|
|
152
|
+
"missing-glyph",
|
|
153
|
+
"mmultiscripts",
|
|
154
|
+
"mn",
|
|
155
|
+
"mo",
|
|
156
|
+
"mover",
|
|
157
|
+
"mpadded",
|
|
158
|
+
"mpath",
|
|
159
|
+
"mphantom",
|
|
160
|
+
"mprescripts",
|
|
161
|
+
"mroot",
|
|
162
|
+
"mrow",
|
|
163
|
+
"ms",
|
|
164
|
+
"mspace",
|
|
165
|
+
"msqrt",
|
|
166
|
+
"mstyle",
|
|
167
|
+
"msub",
|
|
168
|
+
"msubsup",
|
|
169
|
+
"msup",
|
|
170
|
+
"mtable",
|
|
171
|
+
"mtd",
|
|
172
|
+
"mtext",
|
|
173
|
+
"mtr",
|
|
174
|
+
"multicol",
|
|
175
|
+
"munder",
|
|
176
|
+
"munderover",
|
|
177
|
+
"nav",
|
|
178
|
+
"nextid",
|
|
179
|
+
"nobr",
|
|
180
|
+
"noembed",
|
|
181
|
+
"noframes",
|
|
182
|
+
"noscript",
|
|
183
|
+
"object",
|
|
184
|
+
"ol",
|
|
185
|
+
"optgroup",
|
|
186
|
+
"option",
|
|
187
|
+
"output",
|
|
188
|
+
"p",
|
|
189
|
+
"param",
|
|
190
|
+
"path",
|
|
191
|
+
"pattern",
|
|
192
|
+
"picture",
|
|
193
|
+
"plaintext",
|
|
194
|
+
"polygon",
|
|
195
|
+
"polyline",
|
|
196
|
+
"pre",
|
|
197
|
+
"progress",
|
|
198
|
+
"q",
|
|
199
|
+
"radialGradient",
|
|
200
|
+
"rb",
|
|
201
|
+
"rbc",
|
|
202
|
+
"rect",
|
|
203
|
+
"rp",
|
|
204
|
+
"rt",
|
|
205
|
+
"rtc",
|
|
206
|
+
"ruby",
|
|
207
|
+
"s",
|
|
208
|
+
"samp",
|
|
209
|
+
"script",
|
|
210
|
+
"search",
|
|
211
|
+
"section",
|
|
212
|
+
"select",
|
|
213
|
+
"semantics",
|
|
214
|
+
"set",
|
|
215
|
+
"shadow",
|
|
216
|
+
"slot",
|
|
217
|
+
"small",
|
|
218
|
+
"source",
|
|
219
|
+
"spacer",
|
|
220
|
+
"span",
|
|
221
|
+
"stop",
|
|
222
|
+
"strike",
|
|
223
|
+
"strong",
|
|
224
|
+
"style",
|
|
225
|
+
"sub",
|
|
226
|
+
"summary",
|
|
227
|
+
"sup",
|
|
228
|
+
"svg",
|
|
229
|
+
"switch",
|
|
230
|
+
"symbol",
|
|
231
|
+
"table",
|
|
232
|
+
"tbody",
|
|
233
|
+
"td",
|
|
234
|
+
"template",
|
|
235
|
+
"text",
|
|
236
|
+
"textPath",
|
|
237
|
+
"textarea",
|
|
238
|
+
"tfoot",
|
|
239
|
+
"th",
|
|
240
|
+
"thead",
|
|
241
|
+
"time",
|
|
242
|
+
"title",
|
|
243
|
+
"tr",
|
|
244
|
+
"track",
|
|
245
|
+
"tref",
|
|
246
|
+
"tspan",
|
|
247
|
+
"tt",
|
|
248
|
+
"u",
|
|
249
|
+
"ul",
|
|
250
|
+
"use",
|
|
251
|
+
"var",
|
|
252
|
+
"video",
|
|
253
|
+
"view",
|
|
254
|
+
"vkern",
|
|
255
|
+
"wbr",
|
|
256
|
+
"xmp",
|
|
257
|
+
]);
|
package/dist/cjs/vite/index.js
CHANGED
|
@@ -8,7 +8,9 @@ const parser_1 = require("@babel/parser");
|
|
|
8
8
|
const magic_string_1 = __importDefault(require("magic-string"));
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
10
|
const estree_walker_1 = require("estree-walker");
|
|
11
|
+
const domTagNames_js_1 = require("./domTagNames.js");
|
|
11
12
|
const validExtensions = new Set([".jsx", ".tsx"]);
|
|
13
|
+
const fragmentNames = new Set(["Fragment", "React.Fragment"]);
|
|
12
14
|
function getComponentName(elementName) {
|
|
13
15
|
if (elementName.type === "JSXIdentifier") {
|
|
14
16
|
return elementName.name;
|
|
@@ -20,8 +22,17 @@ function getComponentName(elementName) {
|
|
|
20
22
|
}
|
|
21
23
|
return null;
|
|
22
24
|
}
|
|
23
|
-
function
|
|
24
|
-
|
|
25
|
+
function classifyElement(name) {
|
|
26
|
+
if (fragmentNames.has(name)) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
if (!/^[a-z]/.test(name) || name.includes(".")) {
|
|
30
|
+
return "component";
|
|
31
|
+
}
|
|
32
|
+
if (domTagNames_js_1.domTagNames.has(name) || name.includes("-")) {
|
|
33
|
+
return "dom";
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
25
36
|
}
|
|
26
37
|
function ziteId() {
|
|
27
38
|
const cwd = process.cwd();
|
|
@@ -46,21 +57,19 @@ function ziteId() {
|
|
|
46
57
|
if (node.type === "JSXElement") {
|
|
47
58
|
const openingElement = node.openingElement;
|
|
48
59
|
const children = node.children;
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (isFragment) {
|
|
60
|
+
const componentName = getComponentName(openingElement.name);
|
|
61
|
+
if (!componentName) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const kind = classifyElement(componentName);
|
|
65
|
+
if (!kind) {
|
|
56
66
|
return;
|
|
57
67
|
}
|
|
58
68
|
const line = openingElement.loc?.start?.line ?? 0;
|
|
59
69
|
const col = openingElement.loc?.start?.column ?? 0;
|
|
60
70
|
const dataComponentId = `${relativePath}|${line}|${col}`;
|
|
61
71
|
let attributes = ` data-zite-id="${dataComponentId}"`;
|
|
62
|
-
|
|
63
|
-
if (componentName && !isNativeElement(componentName)) {
|
|
72
|
+
if (kind === "component") {
|
|
64
73
|
attributes += ` data-zite-component="${componentName}"`;
|
|
65
74
|
}
|
|
66
75
|
if (children.length === 1 &&
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const path_1 = __importDefault(require("path"));
|
|
7
|
+
const vitest_1 = require("vitest");
|
|
8
|
+
const index_js_1 = require("./index.js");
|
|
9
|
+
async function transform(code) {
|
|
10
|
+
const plugin = (0, index_js_1.ziteId)();
|
|
11
|
+
const handler = plugin.transform;
|
|
12
|
+
const result = await handler(code, path_1.default.join(process.cwd(), 'src/App.tsx'));
|
|
13
|
+
if (!result) {
|
|
14
|
+
throw new Error('transform returned null');
|
|
15
|
+
}
|
|
16
|
+
return result.code;
|
|
17
|
+
}
|
|
18
|
+
(0, vitest_1.describe)('ziteId', () => {
|
|
19
|
+
(0, vitest_1.it)('tags html and svg elements without a component name', async () => {
|
|
20
|
+
const code = await transform('const a = <div><svg><path d="M0" /></svg><p>Hello</p></div>;');
|
|
21
|
+
(0, vitest_1.expect)(code).toContain('<div data-zite-id="src/App.tsx|1|10">');
|
|
22
|
+
(0, vitest_1.expect)(code).toContain('<svg data-zite-id="src/App.tsx|1|15">');
|
|
23
|
+
(0, vitest_1.expect)(code).toContain('<path data-zite-id="src/App.tsx|1|20" d="M0" />');
|
|
24
|
+
(0, vitest_1.expect)(code).toContain('<p data-zite-id="src/App.tsx|1|41" data-zite-editable="true">');
|
|
25
|
+
(0, vitest_1.expect)(code).not.toContain('data-zite-component');
|
|
26
|
+
});
|
|
27
|
+
(0, vitest_1.it)('tags components with their name', async () => {
|
|
28
|
+
const code = await transform('const a = <><Card /><motion.div /><_Private /></>;');
|
|
29
|
+
(0, vitest_1.expect)(code).toContain('<Card data-zite-id="src/App.tsx|1|12" data-zite-component="Card" />');
|
|
30
|
+
(0, vitest_1.expect)(code).toContain('<motion.div data-zite-id="src/App.tsx|1|20" data-zite-component="motion.div" />');
|
|
31
|
+
(0, vitest_1.expect)(code).toContain('<_Private data-zite-id="src/App.tsx|1|34" data-zite-component="_Private" />');
|
|
32
|
+
});
|
|
33
|
+
(0, vitest_1.it)('tags MathML elements', async () => {
|
|
34
|
+
const code = await transform('const a = <math><mi>x</mi></math>;');
|
|
35
|
+
(0, vitest_1.expect)(code).toBe('const a = <math data-zite-id="src/App.tsx|1|10"><mi data-zite-id="src/App.tsx|1|16" data-zite-editable="true">x</mi></math>;');
|
|
36
|
+
});
|
|
37
|
+
(0, vitest_1.it)('tags custom elements', async () => {
|
|
38
|
+
const code = await transform('const a = <my-widget />;');
|
|
39
|
+
(0, vitest_1.expect)(code).toBe('const a = <my-widget data-zite-id="src/App.tsx|1|10" />;');
|
|
40
|
+
});
|
|
41
|
+
(0, vitest_1.it)('leaves non-DOM intrinsic elements untouched', async () => {
|
|
42
|
+
const source = 'const a = <group><mesh position-x={1} /><ambientLight intensity={0.5} /></group>;';
|
|
43
|
+
(0, vitest_1.expect)(await transform(source)).toBe(source);
|
|
44
|
+
});
|
|
45
|
+
(0, vitest_1.it)('tags DOM elements nested inside non-DOM intrinsics', async () => {
|
|
46
|
+
const code = await transform('const a = <group><Html><div /></Html></group>;');
|
|
47
|
+
(0, vitest_1.expect)(code).toBe('const a = <group><Html data-zite-id="src/App.tsx|1|17" data-zite-component="Html"><div data-zite-id="src/App.tsx|1|23" /></Html></group>;');
|
|
48
|
+
});
|
|
49
|
+
(0, vitest_1.it)('leaves fragments untouched', async () => {
|
|
50
|
+
const source = 'const a = <Fragment><React.Fragment key="a" /></Fragment>;';
|
|
51
|
+
(0, vitest_1.expect)(await transform(source)).toBe(source);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -2,3 +2,6 @@ export declare function getFlowId(): string;
|
|
|
2
2
|
export declare function getApiUrl(): string;
|
|
3
3
|
export declare function getAuthPageUrl(): string;
|
|
4
4
|
export declare function getDbToken(): string;
|
|
5
|
+
/** Undefined for apps built before the platform sent this — treat as unknown,
|
|
6
|
+
* never as a default side. */
|
|
7
|
+
export declare function getAccessMode(): 'internal' | 'external' | undefined;
|
package/dist/esm/auth/config.js
CHANGED
|
@@ -30,3 +30,9 @@ export function getAuthPageUrl() {
|
|
|
30
30
|
export function getDbToken() {
|
|
31
31
|
return getEnv('ZITE_DB_TOKEN', 'VITE_ZITE_DB_TOKEN') ?? '';
|
|
32
32
|
}
|
|
33
|
+
/** Undefined for apps built before the platform sent this — treat as unknown,
|
|
34
|
+
* never as a default side. */
|
|
35
|
+
export function getAccessMode() {
|
|
36
|
+
const mode = getEnv('ZITE_ACCESS_MODE', 'VITE_ZITE_ACCESS_MODE');
|
|
37
|
+
return mode === 'internal' || mode === 'external' ? mode : undefined;
|
|
38
|
+
}
|
package/dist/esm/auth/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
1
2
|
import { createAuthClient } from 'better-auth/react';
|
|
2
3
|
import { magicLinkClient, inferAdditionalFields, } from 'better-auth/client/plugins';
|
|
3
4
|
import { USAGE_TOKEN_QUERY_PARAM } from './constants.js';
|
|
5
|
+
import { getAccessMode } from './config.js';
|
|
4
6
|
const authClient = createAuthClient({
|
|
5
7
|
baseURL: '',
|
|
6
8
|
plugins: [
|
|
@@ -14,6 +16,22 @@ const authClient = createAuthClient({
|
|
|
14
16
|
],
|
|
15
17
|
});
|
|
16
18
|
export const useSession = authClient.useSession;
|
|
19
|
+
/**
|
|
20
|
+
* An internal app has no signed-out state — SSO runs before the bundle — so an
|
|
21
|
+
* empty session means it died underneath the app. Only `internal`: elsewhere a
|
|
22
|
+
* signed-out visitor is legitimate.
|
|
23
|
+
*/
|
|
24
|
+
function shouldRedirectSignedOut(isPending, hasUser) {
|
|
25
|
+
if (isPending || hasUser)
|
|
26
|
+
return false;
|
|
27
|
+
if (getAccessMode() !== 'internal')
|
|
28
|
+
return false;
|
|
29
|
+
if (typeof window === 'undefined')
|
|
30
|
+
return false;
|
|
31
|
+
// `loginWithRedirect` won't navigate from an auth page, so claiming a
|
|
32
|
+
// redirect here would hang `isLoading` forever.
|
|
33
|
+
return !window.location.pathname.startsWith('/auth/');
|
|
34
|
+
}
|
|
17
35
|
/**
|
|
18
36
|
* `loginWithRedirect` and `logout` are returned as well as exported. The
|
|
19
37
|
* pre-monorepo `useAuth()` returned them, so app code that destructures them
|
|
@@ -22,9 +40,17 @@ export const useSession = authClient.useSession;
|
|
|
22
40
|
*/
|
|
23
41
|
export function useAuth() {
|
|
24
42
|
const { data, isPending } = useSession();
|
|
43
|
+
const user = data?.user ?? null;
|
|
44
|
+
const redirecting = shouldRedirectSignedOut(isPending, user !== null);
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (redirecting)
|
|
47
|
+
loginWithRedirect();
|
|
48
|
+
}, [redirecting]);
|
|
25
49
|
return {
|
|
26
|
-
user
|
|
27
|
-
|
|
50
|
+
user,
|
|
51
|
+
// Loading, not signed out: the signed-out branch is the empty screen this
|
|
52
|
+
// exists to prevent.
|
|
53
|
+
isLoading: isPending || redirecting,
|
|
28
54
|
loginWithRedirect,
|
|
29
55
|
logout,
|
|
30
56
|
};
|
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect, afterEach, beforeEach, vi } from 'vitest';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
*
|
|
5
|
-
* A separate file from `index.test.ts` because it has to replace
|
|
6
|
-
* `better-auth/react` wholesale to drive `useSession`, and that would strip the
|
|
7
|
-
* real client the export tests next door assert against.
|
|
8
|
-
*
|
|
9
|
-
* The value here is entirely in WHICH signed-out renders it reacts to. An
|
|
10
|
-
* external app has a real logged-out state, and an app built before the
|
|
11
|
-
* platform sent an access mode tells us nothing — redirecting either turns a
|
|
12
|
-
* working public page into a forced sign-in.
|
|
13
|
-
*/
|
|
2
|
+
// Separate from index.test.ts: driving `useSession` means replacing
|
|
3
|
+
// `better-auth/react`, which would strip the real client asserted against there.
|
|
14
4
|
const { useSessionMock } = vi.hoisted(() => ({ useSessionMock: vi.fn() }));
|
|
15
5
|
vi.mock('better-auth/react', () => ({
|
|
16
6
|
createAuthClient: () => ({
|
|
@@ -25,8 +15,7 @@ vi.mock('better-auth/client/plugins', () => ({
|
|
|
25
15
|
magicLinkClient: () => ({}),
|
|
26
16
|
inferAdditionalFields: () => ({}),
|
|
27
17
|
}));
|
|
28
|
-
// `useAuth`
|
|
29
|
-
// of what a render would do here, and avoids pulling in a renderer.
|
|
18
|
+
// `useAuth` uses only `useEffect`; running it inline avoids pulling in a renderer.
|
|
30
19
|
vi.mock('react', () => ({ useEffect: (fn) => fn() }));
|
|
31
20
|
import { useAuth } from './index.js';
|
|
32
21
|
const APP_URL = 'https://app.zite.so/dashboard';
|
|
@@ -55,8 +44,6 @@ describe('useAuth signed-out handling', () => {
|
|
|
55
44
|
it('sends a signed-out visitor on an internal app to sign-in', () => {
|
|
56
45
|
const { result, location } = render(signedOut, { accessMode: 'internal' });
|
|
57
46
|
expect(location.href.startsWith('/auth/login')).toBe(true);
|
|
58
|
-
// Reported as loading rather than signed out: the signed-out branch of an
|
|
59
|
-
// internal app is the empty screen this exists to prevent.
|
|
60
47
|
expect(result.isLoading).toBe(true);
|
|
61
48
|
});
|
|
62
49
|
it('leaves a signed-out visitor on an external app alone', () => {
|
|
@@ -65,7 +52,7 @@ describe('useAuth signed-out handling', () => {
|
|
|
65
52
|
expect(result.isLoading).toBe(false);
|
|
66
53
|
expect(result.user).toBe(null);
|
|
67
54
|
});
|
|
68
|
-
//
|
|
55
|
+
// i.e. every app published before the platform sent an access mode.
|
|
69
56
|
it('leaves an app that never declared an access mode alone', () => {
|
|
70
57
|
const { result, location } = render(signedOut);
|
|
71
58
|
expect(location.href).toBe(APP_URL);
|
|
@@ -82,8 +69,7 @@ describe('useAuth signed-out handling', () => {
|
|
|
82
69
|
expect(result.isLoading).toBe(false);
|
|
83
70
|
expect(result.user).toMatchObject({ id: 'u1' });
|
|
84
71
|
});
|
|
85
|
-
//
|
|
86
|
-
// a redirect here would hang the caller on `isLoading` forever.
|
|
72
|
+
// Claiming a redirect it can't make would hang `isLoading` forever.
|
|
87
73
|
it('does not claim to be loading on an auth page it cannot leave', () => {
|
|
88
74
|
const { result } = render(signedOut, {
|
|
89
75
|
accessMode: 'internal',
|
|
@@ -3,6 +3,27 @@ export type { ZiteSchedule };
|
|
|
3
3
|
export type ZiteWebhook = {
|
|
4
4
|
paused?: boolean;
|
|
5
5
|
};
|
|
6
|
+
/**
|
|
7
|
+
* A provider trigger: what should fire the endpoint, declared as a literal.
|
|
8
|
+
* The platform registers it with the provider at publish, verifies each
|
|
9
|
+
* delivery and queues it; the endpoint only sees the payload. A `poll`
|
|
10
|
+
* trigger runs the endpoint on a cadence with `input.__poll.cursor` from the
|
|
11
|
+
* previous run, and the endpoint returns `{ cursor }` to advance it.
|
|
12
|
+
*/
|
|
13
|
+
export type ZiteTrigger = {
|
|
14
|
+
/**
|
|
15
|
+
* The connection's name in `zite.config.json`. Registered with the
|
|
16
|
+
* provider by `src/triggers/<endpointId>/subscribe.ts` and taken down
|
|
17
|
+
* by `unsubscribe.ts`, which the platform runs at publish and teardown.
|
|
18
|
+
*/
|
|
19
|
+
integration: string;
|
|
20
|
+
paused?: boolean;
|
|
21
|
+
} | {
|
|
22
|
+
provider: "poll";
|
|
23
|
+
/** `<n>m` (1–59) or `<n>h` (1–23) */
|
|
24
|
+
every: string;
|
|
25
|
+
paused?: boolean;
|
|
26
|
+
};
|
|
6
27
|
export interface ZiteRequestContext {
|
|
7
28
|
user: {
|
|
8
29
|
id: string;
|
|
@@ -58,7 +79,7 @@ export type ZiteStreamInterface = {
|
|
|
58
79
|
write: (data: unknown) => Promise<void>;
|
|
59
80
|
forward: (asyncIterable: AsyncIterable<string>) => Promise<string>;
|
|
60
81
|
};
|
|
61
|
-
export interface EndpointConfig<TInput = unknown, TOutput = unknown, TStream extends boolean = false, TSchedule extends ZiteSchedule | undefined = undefined, TWebhook extends ZiteWebhook | undefined = undefined, TRawInput = TInput> {
|
|
82
|
+
export interface EndpointConfig<TInput = unknown, TOutput = unknown, TStream extends boolean = false, TSchedule extends ZiteSchedule | undefined = undefined, TWebhook extends ZiteWebhook | undefined = undefined, TRawInput = TInput, TTrigger extends ZiteTrigger | undefined = undefined> {
|
|
62
83
|
description?: string;
|
|
63
84
|
inputSchema?: SchemaLike<TInput, TRawInput>;
|
|
64
85
|
/**
|
|
@@ -82,6 +103,12 @@ export interface EndpointConfig<TInput = unknown, TOutput = unknown, TStream ext
|
|
|
82
103
|
* `{ user: null }` for a webhook fire exactly as it does for a cron one.
|
|
83
104
|
*/
|
|
84
105
|
webhook?: TWebhook;
|
|
106
|
+
/**
|
|
107
|
+
* When set, the platform fires this endpoint from the named provider. Like
|
|
108
|
+
* `schedule` and `webhook`, this widens `context`: a provider delivery has
|
|
109
|
+
* no signed-in user.
|
|
110
|
+
*/
|
|
111
|
+
trigger?: TTrigger;
|
|
85
112
|
/**
|
|
86
113
|
* Set by {@link createEndpoint}, not by hand. The worker validates
|
|
87
114
|
* `inputSchema` for bundles built before this did, and skips ones that
|
|
@@ -90,7 +117,7 @@ export interface EndpointConfig<TInput = unknown, TOutput = unknown, TStream ext
|
|
|
90
117
|
validatesInput?: boolean;
|
|
91
118
|
execute: (params: {
|
|
92
119
|
input: TInput;
|
|
93
|
-
context: TSchedule extends ZiteSchedule ? ZiteRequestContext | ZiteScheduledContext : TWebhook extends ZiteWebhook ? ZiteRequestContext | ZiteScheduledContext : ZiteRequestContext;
|
|
120
|
+
context: TSchedule extends ZiteSchedule ? ZiteRequestContext | ZiteScheduledContext : TWebhook extends ZiteWebhook ? ZiteRequestContext | ZiteScheduledContext : TTrigger extends ZiteTrigger ? ZiteRequestContext | ZiteScheduledContext : ZiteRequestContext;
|
|
94
121
|
} & (TStream extends true ? {
|
|
95
122
|
stream: ZiteStreamInterface;
|
|
96
123
|
} : {})) => Promise<TOutput> | TOutput;
|
|
@@ -102,4 +129,4 @@ export interface EndpointConfig<TInput = unknown, TOutput = unknown, TStream ext
|
|
|
102
129
|
* field could be missing and the endpoint ran anyway. Parsing here is also what
|
|
103
130
|
* makes `TRawInput` -> `TInput` (defaults, transforms) true at runtime.
|
|
104
131
|
*/
|
|
105
|
-
export declare function createEndpoint<TInput = unknown, TOutput = unknown, TStream extends boolean = false, TSchedule extends ZiteSchedule | undefined = undefined, TWebhook extends ZiteWebhook | undefined = undefined, TRawInput = TInput>(config: EndpointConfig<TInput, TOutput, TStream, TSchedule, TWebhook, TRawInput>): EndpointConfig<TInput, TOutput, TStream, TSchedule, TWebhook, TRawInput>;
|
|
132
|
+
export declare function createEndpoint<TInput = unknown, TOutput = unknown, TStream extends boolean = false, TSchedule extends ZiteSchedule | undefined = undefined, TWebhook extends ZiteWebhook | undefined = undefined, TRawInput = TInput, TTrigger extends ZiteTrigger | undefined = undefined>(config: EndpointConfig<TInput, TOutput, TStream, TSchedule, TWebhook, TRawInput, TTrigger>): EndpointConfig<TInput, TOutput, TStream, TSchedule, TWebhook, TRawInput, TTrigger>;
|
|
@@ -27,7 +27,7 @@ export class ZiteError extends Error {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
/** Injected by the runner on a platform-fired run — see `isPlatformTriggeredInput`. */
|
|
30
|
-
const PLATFORM_TRIGGER_KEYS = ["__cron", "__webhook"];
|
|
30
|
+
const PLATFORM_TRIGGER_KEYS = ["__cron", "__webhook", "__poll"];
|
|
31
31
|
function isPlatformTriggeredInput(input) {
|
|
32
32
|
if (typeof input !== "object" || input === null)
|
|
33
33
|
return false;
|
|
@@ -55,7 +55,7 @@ function describeIssues(error) {
|
|
|
55
55
|
*/
|
|
56
56
|
export function createEndpoint(config) {
|
|
57
57
|
const { inputSchema, execute } = config;
|
|
58
|
-
const firesWithoutARequest = Boolean(config.schedule || config.webhook);
|
|
58
|
+
const firesWithoutARequest = Boolean(config.schedule || config.webhook || config.trigger);
|
|
59
59
|
// An `inputSchema` that isn't a validator stays inert, as it was.
|
|
60
60
|
if (!inputSchema || typeof inputSchema.parse !== "function")
|
|
61
61
|
return config;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Usage:
|
|
10
10
|
* npx zitejs bundle # bundle all endpoints
|
|
11
|
-
* npx zitejs bundle --app admin-panel # bundle endpoints for
|
|
11
|
+
* npx zitejs bundle --app admin-panel # bundle endpoints for one app or automation, by dir name
|
|
12
12
|
* npx zitejs bundle --script <path> # bundle a one-off script
|
|
13
13
|
*
|
|
14
14
|
* Output: JSON to stdout
|
package/dist/esm/bundle/index.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Usage:
|
|
10
10
|
* npx zitejs bundle # bundle all endpoints
|
|
11
|
-
* npx zitejs bundle --app admin-panel # bundle endpoints for
|
|
11
|
+
* npx zitejs bundle --app admin-panel # bundle endpoints for one app or automation, by dir name
|
|
12
12
|
* npx zitejs bundle --script <path> # bundle a one-off script
|
|
13
13
|
*
|
|
14
14
|
* Output: JSON to stdout
|
|
@@ -24,6 +24,7 @@ import * as path from 'path';
|
|
|
24
24
|
import * as fs from 'fs';
|
|
25
25
|
import { parse } from '@babel/parser';
|
|
26
26
|
import { builtinModules } from 'node:module';
|
|
27
|
+
import { findSourceDir } from '../sourceRoots.js';
|
|
27
28
|
// workerd's `nodejs_compat` does not provide these. Left external they bundle
|
|
28
29
|
// fine and then kill the worker at load time with `No such module`; excluded,
|
|
29
30
|
// esbuild fails the one endpoint with a resolvable error instead. Pinned by
|
|
@@ -578,7 +579,10 @@ export async function runBundle() {
|
|
|
578
579
|
const appFlag = args.indexOf('--app');
|
|
579
580
|
let baseDir = process.cwd();
|
|
580
581
|
if (appFlag !== -1 && args[appFlag + 1]) {
|
|
581
|
-
|
|
582
|
+
const name = args[appFlag + 1];
|
|
583
|
+
// A dir that exists under no root still resolves under `apps/`, so the
|
|
584
|
+
// error names the path a caller expects rather than "not found".
|
|
585
|
+
baseDir = path.resolve(baseDir, findSourceDir(name, baseDir)?.path ?? path.join('apps', name));
|
|
582
586
|
}
|
|
583
587
|
// If explicit endpoint names passed, use those; otherwise find all.
|
|
584
588
|
// Skipping `--app`'s VALUE as well as the flag: it is a positional arg, so
|
package/dist/esm/check/index.js
CHANGED
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
import { execFileSync } from 'child_process';
|
|
2
|
-
import { existsSync
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
3
|
import { join } from 'path';
|
|
4
|
-
|
|
5
|
-
const appsDir = 'apps';
|
|
6
|
-
if (!existsSync(appsDir))
|
|
7
|
-
return [];
|
|
8
|
-
return readdirSync(appsDir, { withFileTypes: true })
|
|
9
|
-
.filter(d => d.isDirectory())
|
|
10
|
-
.map(d => d.name);
|
|
11
|
-
}
|
|
4
|
+
import { listSourceDirs } from '../sourceRoots.js';
|
|
12
5
|
/**
|
|
13
6
|
* An argument array, not a command string, so no shell is involved.
|
|
14
7
|
*
|
|
@@ -63,15 +56,14 @@ function bundleFailures(output) {
|
|
|
63
56
|
return failures;
|
|
64
57
|
}
|
|
65
58
|
export async function runCheck() {
|
|
66
|
-
const appDirs =
|
|
59
|
+
const appDirs = listSourceDirs();
|
|
67
60
|
if (appDirs.length === 0) {
|
|
68
|
-
console.error('No apps found
|
|
61
|
+
console.error('No apps or automations found under apps/ or automations/.');
|
|
69
62
|
process.exit(1);
|
|
70
63
|
}
|
|
71
64
|
let allPassed = true;
|
|
72
|
-
for (const app of appDirs) {
|
|
73
|
-
|
|
74
|
-
console.log(`\n── ${app} ──`);
|
|
65
|
+
for (const { dir: app, path: appPath } of appDirs) {
|
|
66
|
+
console.log(`\n── ${appPath} ──`);
|
|
75
67
|
// Only tsconfig.app.json compiles anything. The app's tsconfig.json is a
|
|
76
68
|
// solution-style config — `"files": []` plus a reference — so
|
|
77
69
|
// `tsc --noEmit -p tsconfig.json` type-checks zero files and exits 0. It
|
package/dist/esm/cli.js
CHANGED
|
@@ -38,8 +38,8 @@ async function main() {
|
|
|
38
38
|
console.error('Commands:');
|
|
39
39
|
console.error(' sync Generate .zite/db.ts from database schema (single-app)');
|
|
40
40
|
console.error(' dev Run sync then watch for changes (like npx convex dev)');
|
|
41
|
-
console.error(' generate
|
|
42
|
-
console.error(' check Run tsc --noEmit and vite build for
|
|
41
|
+
console.error(' generate Regenerate every app and automation .zite/ (monorepo)');
|
|
42
|
+
console.error(' check Run tsc --noEmit (and vite build where there is one) for every app and automation');
|
|
43
43
|
console.error(' bundle Bundle src/api/*.ts endpoints for cloudflare-lambda');
|
|
44
44
|
process.exit(1);
|
|
45
45
|
}
|