tempo-sdk 0.0.1 → 0.0.2
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/index.d.ts +3 -6
- package/dist/index.js +57 -16
- package/dist/index.js.map +1 -1
- package/package.json +17 -16
- package/dist/page.d.ts +0 -27
- package/dist/page.js +0 -1
- package/dist/page.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { JSXElement } from 'oxc-parser';
|
|
2
2
|
import { FilterPattern } from '@rollup/pluginutils';
|
|
3
3
|
import { Plugin } from 'vite';
|
|
4
|
-
import {
|
|
4
|
+
import { ReactElement } from 'react';
|
|
5
5
|
|
|
6
6
|
interface ElementInfo {
|
|
7
7
|
element: JSXElement;
|
|
@@ -41,18 +41,15 @@ interface StoryboardLayout {
|
|
|
41
41
|
height: number;
|
|
42
42
|
zIndex?: number;
|
|
43
43
|
}
|
|
44
|
-
interface TempoStoryboard
|
|
45
|
-
|
|
44
|
+
interface TempoStoryboard {
|
|
45
|
+
render: () => ReactElement;
|
|
46
46
|
name?: string;
|
|
47
|
-
args?: Partial<ComponentProps<C>>;
|
|
48
47
|
layout: StoryboardLayout;
|
|
49
|
-
container?: (Story: ComponentType<any>) => ReactElement;
|
|
50
48
|
}
|
|
51
49
|
interface TempoRouteStoryboard {
|
|
52
50
|
route: string;
|
|
53
51
|
name?: string;
|
|
54
52
|
layout: StoryboardLayout;
|
|
55
|
-
container?: (Story: ComponentType<any>) => ReactElement;
|
|
56
53
|
}
|
|
57
54
|
|
|
58
55
|
type ComputeAnnotatedProps = (info: ElementInfo, filepath: string, modifiedtsMs: number) => Record<string, PropValue>;
|
package/dist/index.js
CHANGED
|
@@ -86,7 +86,11 @@ function annotateFile(source, filename, computeAnnotatedProps) {
|
|
|
86
86
|
lastPos = position;
|
|
87
87
|
}
|
|
88
88
|
chunks.push(source.slice(lastPos));
|
|
89
|
-
return {
|
|
89
|
+
return {
|
|
90
|
+
annotatedSource: chunks.join(""),
|
|
91
|
+
elementsAnnotated: insertions.length,
|
|
92
|
+
parseResult
|
|
93
|
+
};
|
|
90
94
|
}
|
|
91
95
|
|
|
92
96
|
// index.ts
|
|
@@ -145,10 +149,14 @@ function loadProject(descriptor) {
|
|
|
145
149
|
path.dirname(tsconfigPath)
|
|
146
150
|
);
|
|
147
151
|
if (parsed.errors.length > 0) {
|
|
148
|
-
const message = parsed.errors.map(
|
|
152
|
+
const message = parsed.errors.map(
|
|
153
|
+
(diagnostic) => ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")
|
|
154
|
+
).join("; ");
|
|
149
155
|
throw new Error(`Failed to parse tsconfig at ${tsconfigPath}: ${message}`);
|
|
150
156
|
}
|
|
151
|
-
const normalizedFiles = parsed.fileNames.map(
|
|
157
|
+
const normalizedFiles = parsed.fileNames.map(
|
|
158
|
+
(fileName) => canonicalPath(fileName)
|
|
159
|
+
);
|
|
152
160
|
return {
|
|
153
161
|
id,
|
|
154
162
|
rootDir,
|
|
@@ -173,10 +181,14 @@ function getFileMtimeVersion(filePath) {
|
|
|
173
181
|
}
|
|
174
182
|
function createTsWorkspaceService(descriptor) {
|
|
175
183
|
if (descriptor.projects.length === 0) {
|
|
176
|
-
throw new Error(
|
|
184
|
+
throw new Error(
|
|
185
|
+
"TsWorkspaceDescriptor.projects must include at least one project"
|
|
186
|
+
);
|
|
177
187
|
}
|
|
178
188
|
const workspaceRoot = canonicalPath(descriptor.workspaceRoot);
|
|
179
|
-
const loadedProjects = descriptor.projects.map(
|
|
189
|
+
const loadedProjects = descriptor.projects.map(
|
|
190
|
+
(project) => loadProject(project)
|
|
191
|
+
);
|
|
180
192
|
const projectsById = /* @__PURE__ */ new Map();
|
|
181
193
|
for (const project of loadedProjects) {
|
|
182
194
|
if (projectsById.has(project.id)) {
|
|
@@ -186,7 +198,9 @@ function createTsWorkspaceService(descriptor) {
|
|
|
186
198
|
}
|
|
187
199
|
const primaryProject = (descriptor.primaryProjectId ? projectsById.get(descriptor.primaryProjectId) : null) ?? loadedProjects[0];
|
|
188
200
|
if (descriptor.primaryProjectId && !projectsById.has(descriptor.primaryProjectId)) {
|
|
189
|
-
throw new Error(
|
|
201
|
+
throw new Error(
|
|
202
|
+
`Primary project id not found: ${descriptor.primaryProjectId}`
|
|
203
|
+
);
|
|
190
204
|
}
|
|
191
205
|
const orderedProjects = [...loadedProjects].sort(compareProjectPriority);
|
|
192
206
|
const rootFileNames = /* @__PURE__ */ new Set();
|
|
@@ -272,7 +286,10 @@ function createTsWorkspaceService(descriptor) {
|
|
|
272
286
|
});
|
|
273
287
|
}
|
|
274
288
|
};
|
|
275
|
-
const languageService = ts.createLanguageService(
|
|
289
|
+
const languageService = ts.createLanguageService(
|
|
290
|
+
host,
|
|
291
|
+
ts.createDocumentRegistry()
|
|
292
|
+
);
|
|
276
293
|
return {
|
|
277
294
|
updateFile(filePath, content) {
|
|
278
295
|
const canonicalFilePath = canonicalPath(filePath);
|
|
@@ -300,7 +317,10 @@ function createTsWorkspaceService(descriptor) {
|
|
|
300
317
|
},
|
|
301
318
|
getDefinition(filePath, position) {
|
|
302
319
|
const canonicalFilePath = canonicalPath(filePath);
|
|
303
|
-
return languageService.getDefinitionAtPosition(
|
|
320
|
+
return languageService.getDefinitionAtPosition(
|
|
321
|
+
canonicalFilePath,
|
|
322
|
+
position
|
|
323
|
+
);
|
|
304
324
|
},
|
|
305
325
|
dispose() {
|
|
306
326
|
languageService.dispose();
|
|
@@ -333,7 +353,9 @@ function parseManagedTsconfigPaths(rawConfig) {
|
|
|
333
353
|
if (!Array.isArray(managedPaths)) {
|
|
334
354
|
return [];
|
|
335
355
|
}
|
|
336
|
-
return managedPaths.filter(
|
|
356
|
+
return managedPaths.filter(
|
|
357
|
+
(entry) => typeof entry === "string" && entry.trim().length > 0
|
|
358
|
+
);
|
|
337
359
|
}
|
|
338
360
|
function parseProjectReferenceTsconfigPaths(references, configDir) {
|
|
339
361
|
if (!references || references.length === 0) {
|
|
@@ -362,11 +384,17 @@ function buildWorkspaceProjects(root, configPath, parsedConfig, rawConfig) {
|
|
|
362
384
|
}
|
|
363
385
|
];
|
|
364
386
|
const seenTsconfigPaths = /* @__PURE__ */ new Set([canonicalPath2(configPath)]);
|
|
365
|
-
const referencedTsconfigPaths = parseProjectReferenceTsconfigPaths(
|
|
387
|
+
const referencedTsconfigPaths = parseProjectReferenceTsconfigPaths(
|
|
388
|
+
parsedConfig.projectReferences,
|
|
389
|
+
configDir
|
|
390
|
+
);
|
|
366
391
|
const managedTsconfigPaths = parseManagedTsconfigPaths(rawConfig).map(
|
|
367
392
|
(entry) => path2.resolve(configDir, entry)
|
|
368
393
|
);
|
|
369
|
-
const candidateTsconfigPaths = [
|
|
394
|
+
const candidateTsconfigPaths = [
|
|
395
|
+
...managedTsconfigPaths,
|
|
396
|
+
...referencedTsconfigPaths
|
|
397
|
+
];
|
|
370
398
|
for (const candidatePath of candidateTsconfigPaths) {
|
|
371
399
|
const normalizedPath = canonicalPath2(candidatePath);
|
|
372
400
|
if (seenTsconfigPaths.has(normalizedPath)) {
|
|
@@ -386,7 +414,11 @@ function buildWorkspaceProjects(root, configPath, parsedConfig, rawConfig) {
|
|
|
386
414
|
return projects;
|
|
387
415
|
}
|
|
388
416
|
function createTypeAnalyzer(root) {
|
|
389
|
-
const configPath = ts2.findConfigFile(
|
|
417
|
+
const configPath = ts2.findConfigFile(
|
|
418
|
+
root,
|
|
419
|
+
ts2.sys.fileExists,
|
|
420
|
+
"tsconfig.json"
|
|
421
|
+
);
|
|
390
422
|
if (!configPath) return null;
|
|
391
423
|
const configFile = ts2.readConfigFile(configPath, ts2.sys.readFile);
|
|
392
424
|
if (configFile.error) return null;
|
|
@@ -395,8 +427,15 @@ function createTypeAnalyzer(root) {
|
|
|
395
427
|
ts2.sys,
|
|
396
428
|
root
|
|
397
429
|
);
|
|
398
|
-
const workspaceProjects = buildWorkspaceProjects(
|
|
399
|
-
|
|
430
|
+
const workspaceProjects = buildWorkspaceProjects(
|
|
431
|
+
root,
|
|
432
|
+
configPath,
|
|
433
|
+
parsedConfig,
|
|
434
|
+
configFile.config
|
|
435
|
+
);
|
|
436
|
+
const workspaceProjectRoots = workspaceProjects.map(
|
|
437
|
+
(project) => canonicalPath2(project.rootDir)
|
|
438
|
+
);
|
|
400
439
|
const workspaceService = createTsWorkspaceService({
|
|
401
440
|
workspaceRoot: root,
|
|
402
441
|
primaryProjectId: "root",
|
|
@@ -524,6 +563,7 @@ function defaultComputeAnnotatedProps(info, filepath, modifiedtsMs) {
|
|
|
524
563
|
};
|
|
525
564
|
}
|
|
526
565
|
function tempoAnnotate(options = {}) {
|
|
566
|
+
const enabled = !!process.env.TEMPO;
|
|
527
567
|
const include = options.include === void 0 ? DEFAULT_INCLUDE : options.include;
|
|
528
568
|
const exclude = options.exclude === void 0 ? DEFAULT_EXCLUDE : options.exclude;
|
|
529
569
|
const filter = createFilter(include, exclude);
|
|
@@ -535,6 +575,7 @@ function tempoAnnotate(options = {}) {
|
|
|
535
575
|
name: "tempo-annotate",
|
|
536
576
|
enforce: "pre",
|
|
537
577
|
configResolved(resolvedConfig) {
|
|
578
|
+
if (!enabled) return;
|
|
538
579
|
command = resolvedConfig.command;
|
|
539
580
|
canonicalRoot = resolveCanonicalRoot(resolvedConfig.root);
|
|
540
581
|
if (command === "serve") {
|
|
@@ -542,7 +583,7 @@ function tempoAnnotate(options = {}) {
|
|
|
542
583
|
}
|
|
543
584
|
},
|
|
544
585
|
transformIndexHtml(html) {
|
|
545
|
-
if (command !== "serve") {
|
|
586
|
+
if (!enabled || command !== "serve") {
|
|
546
587
|
return;
|
|
547
588
|
}
|
|
548
589
|
if (hasRootMetaTag(html)) {
|
|
@@ -560,7 +601,7 @@ function tempoAnnotate(options = {}) {
|
|
|
560
601
|
];
|
|
561
602
|
},
|
|
562
603
|
transform(source, id) {
|
|
563
|
-
if (command === "build") {
|
|
604
|
+
if (!enabled || command === "build") {
|
|
564
605
|
return null;
|
|
565
606
|
}
|
|
566
607
|
if (id.startsWith("\0")) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../index.ts","../../../modules/annotation/annotate-file.ts","../../../modules/file-parser/utils.ts","../../../modules/file-parser/walk.ts","../type-analyzer.ts","../../../modules/typescript/workspace-service.ts"],"sourcesContent":["import { realpathSync, statSync } from \"node:fs\";\nimport { relative } from \"node:path\";\n\nimport {\n annotateFile,\n type ElementInfo,\n type PropValue,\n} from \"../../modules/annotation/annotate-file.ts\";\nimport { createFilter, type FilterPattern } from \"@rollup/pluginutils\";\nimport type { Plugin, ResolvedConfig } from \"vite\";\nimport { createTypeAnalyzer, type TypeAnalyzer } from \"./type-analyzer.ts\";\n\nconst DEFAULT_INCLUDE: FilterPattern = [\"**/*.tsx\", \"**/*.jsx\"];\nconst DEFAULT_EXCLUDE: FilterPattern = [\"**/node_modules/**\"];\nconst ROOT_META_NAME = \"tempo-project-root\";\n\nfunction cleanModuleId(id: string): string {\n return id.replace(/[?#].*$/, \"\");\n}\n\nfunction resolveCanonicalRoot(root: string): string {\n try {\n return realpathSync.native(root);\n } catch {\n return root;\n }\n}\n\nfunction hasRootMetaTag(html: string): boolean {\n return /<meta[^>]+name=[\"']tempo-project-root[\"'][^>]*>/i.test(html);\n}\n\nfunction isIntrinsicElement(tagName: string): boolean {\n return tagName.length > 0 && tagName[0] === tagName[0]!.toLowerCase();\n}\n\nfunction defaultComputeAnnotatedProps(\n info: ElementInfo,\n filepath: string,\n modifiedtsMs: number,\n): Record<string, PropValue> {\n return {\n \"data-tempo-filepath\": filepath,\n \"data-tempo-position\": info.element.openingElement.start,\n \"data-tempo-modifiedts\": modifiedtsMs,\n };\n}\n\nexport type ComputeAnnotatedProps = (\n info: ElementInfo,\n filepath: string,\n modifiedtsMs: number,\n) => Record<string, PropValue>;\n\nexport interface TempoAnnotateOptions {\n computeAnnotatedProps?: ComputeAnnotatedProps;\n include?: FilterPattern;\n exclude?: FilterPattern;\n}\n\nexport function tempoAnnotate(options: TempoAnnotateOptions = {}): Plugin {\n const include =\n options.include === undefined ? DEFAULT_INCLUDE : options.include;\n const exclude =\n options.exclude === undefined ? DEFAULT_EXCLUDE : options.exclude;\n const filter = createFilter(include, exclude);\n\n const computeAnnotatedProps =\n options.computeAnnotatedProps ?? defaultComputeAnnotatedProps;\n\n let canonicalRoot = process.cwd();\n let command: ResolvedConfig[\"command\"] = \"serve\";\n let typeAnalyzer: TypeAnalyzer | null = null;\n\n return {\n name: \"tempo-annotate\",\n enforce: \"pre\",\n configResolved(resolvedConfig) {\n command = resolvedConfig.command;\n canonicalRoot = resolveCanonicalRoot(resolvedConfig.root);\n\n if (command === \"serve\") {\n typeAnalyzer = createTypeAnalyzer(canonicalRoot);\n }\n },\n transformIndexHtml(html) {\n if (command !== \"serve\") {\n return;\n }\n\n if (hasRootMetaTag(html)) {\n return;\n }\n\n return [\n {\n tag: \"meta\",\n attrs: {\n name: ROOT_META_NAME,\n content: canonicalRoot,\n },\n injectTo: \"head\",\n },\n ];\n },\n transform(source, id) {\n if (command === \"build\") {\n return null;\n }\n\n if (id.startsWith(\"\\0\")) {\n return null;\n }\n\n const cleanId = cleanModuleId(id);\n if (!filter(cleanId)) {\n return null;\n }\n\n try {\n const filepath = relative(canonicalRoot, cleanId);\n const modifiedtsMs = Math.trunc(statSync(cleanId).mtimeMs);\n\n const typeInfo = typeAnalyzer?.analyzeFileTypes(cleanId, source);\n\n const result = annotateFile(source, cleanId, (info) => {\n const userProps = computeAnnotatedProps(info, filepath, modifiedtsMs);\n\n // Intrinsic HTML elements always support style and className — no annotation needed\n if (isIntrinsicElement(info.tagName)) {\n return userProps;\n }\n\n // Custom components: look up type support by position, default to false\n const support = typeInfo?.get(info.element.openingElement.start);\n return {\n ...userProps,\n \"data-tempo-supports-style\": support?.supportsStyle ?? false,\n \"data-tempo-supports-classname\": support?.supportsClassName ?? false,\n };\n });\n\n if (result.elementsAnnotated === 0) {\n return null;\n }\n\n return {\n code: result.annotatedSource,\n map: null,\n };\n } catch {\n return null;\n }\n },\n };\n}\n\nexport type { ElementInfo, PropValue };\n\nexport type { ElementTypeSupport, FileTypeInfo, TypeAnalyzer } from \"./type-analyzer.ts\";\nexport { createTypeAnalyzer } from \"./type-analyzer.ts\";\n\nexport type {\n TempoPage,\n StoryboardLayout,\n TempoStoryboard,\n TempoRouteStoryboard,\n} from \"./page.ts\";\n","import { parseSync, type JSXElement, type ParseResult } from 'oxc-parser';\nimport { getTagName } from '../file-parser/utils.ts';\nimport { walk } from '../file-parser/walk.ts';\n\nexport interface ElementInfo {\n element: JSXElement;\n /** e.g. \"div\", \"Button\", \"Foo.Bar\" */\n tagName: string;\n}\n\n/** Supported prop value types. `undefined` values are skipped. */\nexport type PropValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | ((...args: unknown[]) => unknown)\n | object;\n\nfunction formatPropValue(value: PropValue): string | null {\n if (value === undefined) return null;\n if (typeof value === 'function') return value.toString();\n return JSON.stringify(value);\n}\n\nfunction formatProps(props: Record<string, PropValue>): string {\n return Object.entries(props)\n .map(([key, value]) => {\n const formatted = formatPropValue(value);\n if (formatted === null) return null;\n return ` ${key}={${formatted}}`;\n })\n .filter((s): s is string => s !== null)\n .join('');\n}\n\nexport interface AnnotateFileResult {\n annotatedSource: string;\n elementsAnnotated: number;\n /** The oxc-parser result. Check `parseResult.errors` for any parse errors. */\n parseResult: ParseResult;\n}\n\n/** Tag names that represent React fragments and should not be annotated */\nconst FRAGMENT_TAG_NAMES = new Set(['Fragment', 'React.Fragment']);\n\n/**\n * Annotates JSX elements in a source file by inserting additional props.\n *\n * Visits every JSXElement in source order and calls the handler to compute\n * props to insert. Props are inserted at the end of each opening tag.\n *\n * Fragments are skipped since they don't render DOM elements:\n * - JSX shorthand fragments (`<>...</>`) are a separate AST node type\n * - `React.Fragment` and `Fragment` are skipped by tag name\n */\nexport function annotateFile(\n source: string,\n filename: string,\n computeAnnotatedProps: (info: ElementInfo) => Record<string, PropValue>\n): AnnotateFileResult {\n const parseResult = parseSync(filename, source);\n const insertions: { position: number; text: string }[] = [];\n\n // Walk the AST to find all JSXElement nodes\n // Uses our own walker instead of oxc-parser's Visitor (CJS/ESM interop issue in Electron)\n walk(parseResult.program, {\n JSXElement(node: unknown) {\n const element = node as JSXElement;\n const tagName = getTagName(element.openingElement.name);\n if (FRAGMENT_TAG_NAMES.has(tagName)) return;\n\n const props = computeAnnotatedProps({ element, tagName });\n if (Object.keys(props).length === 0) return;\n\n const openingElement = element.openingElement;\n\n // Insert before \">\" or \"/>\" at end of opening tag, skipping whitespace before \"/>\"\n let insertPos = openingElement.end - 1;\n if (openingElement.selfClosing) {\n insertPos--;\n while (insertPos > openingElement.start && /\\s/.test(source[insertPos - 1]!)) {\n insertPos--;\n }\n }\n\n insertions.push({ position: insertPos, text: formatProps(props) });\n },\n });\n\n // Build result in a single pass using chunks (O(n) instead of O(n*m))\n insertions.sort((a, b) => a.position - b.position);\n\n const chunks: string[] = [];\n let lastPos = 0;\n for (const { position, text } of insertions) {\n chunks.push(source.slice(lastPos, position));\n chunks.push(text);\n lastPos = position;\n }\n chunks.push(source.slice(lastPos));\n\n return { annotatedSource: chunks.join(''), elementsAnnotated: insertions.length, parseResult };\n}\n","\n/**\n * Annotation Utilities\n *\n * Helper functions for working with oxc-parser AST nodes.\n */\n\nimport type { JSXElementName, JSXMemberExpression } from 'oxc-parser';\n\n/**\n * Extracts the tag name string from any JSXElementName variant.\n *\n * JSXElementName is a union of three types representing different JSX tag syntaxes:\n * - JSXIdentifier: `<button>` → \"button\", `<Button>` → \"Button\"\n * - JSXNamespacedName: `<svg:rect>` → \"svg:rect\" (rare, used in SVG/XML)\n * - JSXMemberExpression: `<Foo.Bar>` → \"Foo.Bar\", `<UI.Button.Primary>` → \"UI.Button.Primary\"\n */\nexport function getTagName(name: JSXElementName): string {\n switch (name.type) {\n case 'JSXIdentifier':\n return name.name;\n case 'JSXNamespacedName':\n return `${name.namespace.name}:${name.name.name}`;\n case 'JSXMemberExpression':\n return getJSXMemberExpressionName(name);\n }\n}\n\n/**\n * Recursively builds the dotted name string from a JSXMemberExpression.\n *\n * JSXMemberExpression represents dotted component names like `<Foo.Bar.Baz>`:\n * - object: either a JSXIdentifier or another JSXMemberExpression (for chaining)\n * - property: always a JSXIdentifier (the rightmost part)\n */\nexport function getJSXMemberExpressionName(node: JSXMemberExpression): string {\n const object = node.object.type === 'JSXIdentifier' ? node.object.name : getJSXMemberExpressionName(node.object);\n return `${object}.${node.property.name}`;\n}\n","/**\n * AST Walker\n *\n * Simple recursive walker for oxc-parser ASTs. Visits every node in the tree\n * and calls type-specific callbacks. Drop-in replacement for oxc-parser's\n * Visitor class, which has CJS/ESM interop issues in Electron.\n *\n * Once oxc-parser's Visitor works in Electron, this can be swapped back.\n */\n\n/**\n * Callbacks for specific AST node types.\n * Add more node types here as needed.\n */\nexport interface WalkCallbacks {\n JSXElement?: (node: any) => void;\n}\n\n/**\n * Recursively walks an oxc-parser AST, calling callbacks for matching node types.\n * Traverses all object properties and array elements depth-first.\n */\nexport function walk(node: unknown, callbacks: WalkCallbacks): void {\n if (node === null || node === undefined || typeof node !== \"object\") return;\n\n if (Array.isArray(node)) {\n for (const child of node) {\n walk(child, callbacks);\n }\n return;\n }\n\n const record = node as Record<string, unknown>;\n const type = record.type;\n\n if (typeof type === \"string\" && type in callbacks) {\n (callbacks as Record<string, (node: unknown) => void>)[type]!(node);\n }\n\n for (const value of Object.values(record)) {\n if (value !== null && typeof value === \"object\") {\n walk(value, callbacks);\n }\n }\n}\n","/**\n * TypeScript type analyzer for JSX element prop support.\n *\n * Uses a TypeScript Language Service to determine whether each custom React\n * component supports `style` (CSSProperties-compatible) and `className`\n * (string-compatible) props. Correlation between OXC and TypeScript ASTs is\n * position-based — both use UTF-16 string indices, so element positions can\n * be compared directly.\n *\n * Intrinsic HTML elements are excluded from the analysis entirely — the\n * consumer already knows they support both from the HTML standard.\n */\nimport ts from \"typescript\";\nimport path from \"node:path\";\nimport { realpathSync } from \"node:fs\";\nimport {\n createTsWorkspaceService,\n type TsProjectDescriptor,\n type TsWorkspaceService,\n} from \"@modules/typescript\";\n\nexport interface ElementTypeSupport {\n supportsStyle: boolean;\n supportsClassName: boolean;\n}\n\n/** Position → type support for custom components only */\nexport type FileTypeInfo = Map<number, ElementTypeSupport>;\n\nexport interface TypeAnalyzer {\n analyzeFileTypes(filePath: string, source: string): FileTypeInfo | null;\n}\n\n/** Custom component if first character is uppercase or it's a member expression */\nfunction isCustomComponent(node: ts.JsxTagNameExpression): boolean {\n const text = node.getText();\n return text.length > 0 && text[0] !== text[0]!.toLowerCase();\n}\n\ninterface TempobookTsMetadata {\n managedTsconfigPaths?: unknown;\n}\n\nfunction canonicalPath(value: string): string {\n const resolved = path.resolve(value);\n try {\n return realpathSync.native(resolved);\n } catch {\n return resolved;\n }\n}\n\nfunction parseManagedTsconfigPaths(rawConfig: unknown): string[] {\n if (!rawConfig || typeof rawConfig !== \"object\" || Array.isArray(rawConfig)) {\n return [];\n }\n\n const metadata = (rawConfig as { tempobook?: TempobookTsMetadata }).tempobook;\n if (!metadata || typeof metadata !== \"object\" || Array.isArray(metadata)) {\n return [];\n }\n\n const managedPaths = metadata.managedTsconfigPaths;\n if (!Array.isArray(managedPaths)) {\n return [];\n }\n\n return managedPaths.filter((entry): entry is string => typeof entry === \"string\" && entry.trim().length > 0);\n}\n\nfunction parseProjectReferenceTsconfigPaths(\n references: readonly ts.ProjectReference[] | undefined,\n configDir: string,\n): string[] {\n if (!references || references.length === 0) {\n return [];\n }\n\n const entries: string[] = [];\n for (const reference of references) {\n const referencePath = reference.path;\n if (!referencePath) {\n continue;\n }\n\n const resolvedPath = path.resolve(configDir, referencePath);\n const tsconfigPath = resolvedPath.endsWith(\".json\")\n ? resolvedPath\n : path.join(resolvedPath, \"tsconfig.json\");\n\n entries.push(tsconfigPath);\n }\n\n return entries;\n}\n\nfunction buildWorkspaceProjects(\n root: string,\n configPath: string,\n parsedConfig: ts.ParsedCommandLine,\n rawConfig: unknown,\n): TsProjectDescriptor[] {\n const configDir = path.dirname(configPath);\n const projects: TsProjectDescriptor[] = [\n {\n id: \"root\",\n rootDir: root,\n tsconfigPath: configPath,\n priority: 0,\n },\n ];\n\n const seenTsconfigPaths = new Set<string>([canonicalPath(configPath)]);\n const referencedTsconfigPaths = parseProjectReferenceTsconfigPaths(parsedConfig.projectReferences, configDir);\n const managedTsconfigPaths = parseManagedTsconfigPaths(rawConfig).map((entry) =>\n path.resolve(configDir, entry),\n );\n\n const candidateTsconfigPaths = [...managedTsconfigPaths, ...referencedTsconfigPaths];\n for (const candidatePath of candidateTsconfigPaths) {\n const normalizedPath = canonicalPath(candidatePath);\n if (seenTsconfigPaths.has(normalizedPath)) {\n continue;\n }\n if (!ts.sys.fileExists(normalizedPath)) {\n continue;\n }\n\n seenTsconfigPaths.add(normalizedPath);\n projects.push({\n id: `external-${projects.length}`,\n rootDir: path.dirname(normalizedPath),\n tsconfigPath: normalizedPath,\n priority: 0,\n });\n }\n\n return projects;\n}\n\n/**\n * Create a type analyzer backed by a TypeScript Language Service.\n *\n * The Language Service provides incremental updates — when a file changes,\n * we bump its version and provide the new content. The service lazily\n * recomputes only what's needed.\n *\n * Returns null if no tsconfig.json is found.\n */\nexport function createTypeAnalyzer(root: string): TypeAnalyzer | null {\n const configPath = ts.findConfigFile(root, ts.sys.fileExists, \"tsconfig.json\");\n if (!configPath) return null;\n\n const configFile = ts.readConfigFile(configPath, ts.sys.readFile);\n if (configFile.error) return null;\n\n const parsedConfig = ts.parseJsonConfigFileContent(\n configFile.config,\n ts.sys,\n root,\n );\n\n const workspaceProjects = buildWorkspaceProjects(root, configPath, parsedConfig, configFile.config);\n const workspaceProjectRoots = workspaceProjects.map((project) => canonicalPath(project.rootDir));\n\n const workspaceService: TsWorkspaceService = createTsWorkspaceService({\n workspaceRoot: root,\n primaryProjectId: \"root\",\n projects: workspaceProjects,\n });\n\n // Lazily resolved CSSProperties type for style compatibility checks.\n // Resolved from JSX.IntrinsicElements['div'].style, with the undefined\n // union member stripped to get the pure CSSProperties type.\n let cssPropertiesType: ts.Type | null | undefined;\n\n function resolveCSSPropertiesType(\n checker: ts.TypeChecker,\n sourceFile: ts.SourceFile,\n ): ts.Type | null {\n if (cssPropertiesType !== undefined) return cssPropertiesType;\n\n try {\n // JSX namespace → IntrinsicElements → div → style → unwrap undefined\n const jsxNs = (checker as any).resolveName(\n \"JSX\", sourceFile, ts.SymbolFlags.Namespace, false,\n );\n if (!jsxNs) { cssPropertiesType = null; return null; }\n\n const intrinsicSym = checker.getExportsOfModule(jsxNs)\n .find((s) => s.name === \"IntrinsicElements\");\n if (!intrinsicSym) { cssPropertiesType = null; return null; }\n\n const divSym = checker.getDeclaredTypeOfSymbol(intrinsicSym)\n .getProperty(\"div\");\n if (!divSym) { cssPropertiesType = null; return null; }\n\n const styleSym = checker.getTypeOfSymbol(divSym).getProperty(\"style\");\n if (!styleSym) { cssPropertiesType = null; return null; }\n\n const styleType = checker.getTypeOfSymbol(styleSym);\n\n // styleType is CSSProperties | undefined — extract the non-undefined member\n if (styleType.isUnion()) {\n const nonUndefined = styleType.types.find(\n (t) => !(t.flags & ts.TypeFlags.Undefined),\n );\n cssPropertiesType = nonUndefined ?? null;\n } else {\n cssPropertiesType = styleType;\n }\n } catch {\n cssPropertiesType = null;\n }\n\n return cssPropertiesType;\n }\n\n return {\n analyzeFileTypes(filePath: string, source: string): FileTypeInfo | null {\n const canonicalFilePath = canonicalPath(filePath);\n const belongsToWorkspace = workspaceProjectRoots.some(\n (projectRoot) =>\n canonicalFilePath === projectRoot ||\n canonicalFilePath.startsWith(`${projectRoot}${path.sep}`),\n );\n if (!belongsToWorkspace) {\n return null;\n }\n\n // Update the workspace service with current in-memory source.\n workspaceService.updateFile(filePath, source);\n\n const program = workspaceService.getProgram();\n if (!program) return null;\n\n const sourceFile = program.getSourceFile(filePath);\n if (!sourceFile) return null;\n\n const checker = program.getTypeChecker();\n const cssProps = resolveCSSPropertiesType(checker, sourceFile);\n const result: FileTypeInfo = new Map();\n\n function visit(node: ts.Node) {\n if (\n (ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) &&\n isCustomComponent(node.tagName)\n ) {\n const position = node.getStart(sourceFile);\n const attrsType = checker.getContextualType(node.attributes);\n\n let supportsStyle = false;\n let supportsClassName = false;\n\n if (attrsType) {\n // className: check that `string` is assignable to the prop's type\n const classNameProp = attrsType.getProperty(\"className\");\n if (classNameProp) {\n const propType = checker.getTypeOfSymbol(classNameProp);\n supportsClassName = (checker as any).isTypeAssignableTo(\n checker.getStringType(), propType,\n );\n }\n\n // style: check that CSSProperties is assignable to the prop's type\n const styleProp = attrsType.getProperty(\"style\");\n if (styleProp && cssProps) {\n const propType = checker.getTypeOfSymbol(styleProp);\n supportsStyle = (checker as any).isTypeAssignableTo(\n cssProps, propType,\n );\n }\n }\n\n result.set(position, { supportsStyle, supportsClassName });\n }\n\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return result;\n },\n };\n}\n","import { realpathSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\n\nimport ts from \"typescript\";\n\nexport interface TsProjectDescriptor {\n id: string;\n rootDir: string;\n tsconfigPath: string;\n priority?: number;\n}\n\nexport interface TsWorkspaceDescriptor {\n workspaceRoot: string;\n projects: TsProjectDescriptor[];\n primaryProjectId?: string;\n}\n\nexport interface TsWorkspaceService {\n updateFile(filePath: string, content: string): void;\n closeFile(filePath: string): void;\n getProgram(): ts.Program | null;\n getSemanticDiagnostics(filePath: string): readonly ts.Diagnostic[];\n getDefinition(filePath: string, position: number): readonly ts.DefinitionInfo[] | undefined;\n dispose(): void;\n}\n\ninterface LoadedProject {\n id: string;\n rootDir: string;\n tsconfigPath: string;\n priority: number;\n options: ts.CompilerOptions;\n fileNames: string[];\n moduleResolutionCache: ts.ModuleResolutionCache;\n}\n\ninterface InMemoryFile {\n version: number;\n content: string;\n}\n\nfunction canonicalPath(input: string): string {\n const resolved = path.resolve(input);\n try {\n return realpathSync.native(resolved);\n } catch {\n return resolved;\n }\n}\n\nfunction compareProjectPriority(left: LoadedProject, right: LoadedProject): number {\n const depthDelta = right.rootDir.length - left.rootDir.length;\n if (depthDelta !== 0) {\n return depthDelta;\n }\n\n const priorityDelta = right.priority - left.priority;\n if (priorityDelta !== 0) {\n return priorityDelta;\n }\n\n return left.id.localeCompare(right.id);\n}\n\nfunction isWithinRoot(filePath: string, rootDir: string): boolean {\n return filePath === rootDir || filePath.startsWith(`${rootDir}${path.sep}`);\n}\n\nfunction loadProject(descriptor: TsProjectDescriptor): LoadedProject {\n const id = descriptor.id.trim();\n if (!id) {\n throw new Error(\"Project id must be a non-empty string\");\n }\n\n const tsconfigPath = canonicalPath(descriptor.tsconfigPath);\n const rootDir = canonicalPath(descriptor.rootDir);\n\n const readResult = ts.readConfigFile(tsconfigPath, ts.sys.readFile);\n if (readResult.error) {\n throw new Error(\n `Failed to read tsconfig at ${tsconfigPath}: ${ts.flattenDiagnosticMessageText(\n readResult.error.messageText,\n \"\\n\",\n )}`,\n );\n }\n\n const parsed = ts.parseJsonConfigFileContent(\n readResult.config,\n ts.sys,\n path.dirname(tsconfigPath),\n );\n\n if (parsed.errors.length > 0) {\n const message = parsed.errors\n .map((diagnostic) => ts.flattenDiagnosticMessageText(diagnostic.messageText, \"\\n\"))\n .join(\"; \");\n throw new Error(`Failed to parse tsconfig at ${tsconfigPath}: ${message}`);\n }\n\n const normalizedFiles = parsed.fileNames.map((fileName) => canonicalPath(fileName));\n return {\n id,\n rootDir,\n tsconfigPath,\n priority: descriptor.priority ?? 0,\n options: parsed.options,\n fileNames: normalizedFiles,\n moduleResolutionCache: ts.createModuleResolutionCache(\n rootDir,\n (value) => value,\n parsed.options,\n ),\n };\n}\n\nfunction getFileMtimeVersion(filePath: string): string {\n try {\n const stats = statSync(filePath);\n return String(stats.mtimeMs);\n } catch {\n return \"0\";\n }\n}\n\nexport function createTsWorkspaceService(\n descriptor: TsWorkspaceDescriptor,\n): TsWorkspaceService {\n if (descriptor.projects.length === 0) {\n throw new Error(\"TsWorkspaceDescriptor.projects must include at least one project\");\n }\n\n const workspaceRoot = canonicalPath(descriptor.workspaceRoot);\n const loadedProjects = descriptor.projects.map((project) => loadProject(project));\n\n const projectsById = new Map<string, LoadedProject>();\n for (const project of loadedProjects) {\n if (projectsById.has(project.id)) {\n throw new Error(`Duplicate project id: ${project.id}`);\n }\n projectsById.set(project.id, project);\n }\n\n const primaryProject =\n (descriptor.primaryProjectId ? projectsById.get(descriptor.primaryProjectId) : null) ??\n loadedProjects[0]!;\n if (descriptor.primaryProjectId && !projectsById.has(descriptor.primaryProjectId)) {\n throw new Error(`Primary project id not found: ${descriptor.primaryProjectId}`);\n }\n\n const orderedProjects = [...loadedProjects].sort(compareProjectPriority);\n const rootFileNames = new Set<string>();\n for (const project of loadedProjects) {\n for (const fileName of project.fileNames) {\n rootFileNames.add(fileName);\n }\n }\n\n const inMemoryFiles = new Map<string, InMemoryFile>();\n let projectVersion = 0;\n\n function getOwningProject(filePath: string): LoadedProject {\n const canonicalFilePath = canonicalPath(filePath);\n for (const project of orderedProjects) {\n if (isWithinRoot(canonicalFilePath, project.rootDir)) {\n return project;\n }\n }\n return primaryProject;\n }\n\n const moduleResolutionHost: ts.ModuleResolutionHost = {\n fileExists: ts.sys.fileExists,\n readFile: ts.sys.readFile,\n realpath: ts.sys.realpath,\n directoryExists: ts.sys.directoryExists,\n getCurrentDirectory: () => workspaceRoot,\n getDirectories: ts.sys.getDirectories,\n };\n\n const host: ts.LanguageServiceHost = {\n getScriptFileNames: () => Array.from(rootFileNames),\n getScriptVersion: (filePath) => {\n const canonicalFilePath = canonicalPath(filePath);\n const inMemory = inMemoryFiles.get(canonicalFilePath);\n if (inMemory) {\n return String(inMemory.version);\n }\n return getFileMtimeVersion(canonicalFilePath);\n },\n getScriptSnapshot: (filePath) => {\n const canonicalFilePath = canonicalPath(filePath);\n const inMemory = inMemoryFiles.get(canonicalFilePath);\n if (inMemory) {\n return ts.ScriptSnapshot.fromString(inMemory.content);\n }\n\n const diskContent = ts.sys.readFile(canonicalFilePath);\n if (diskContent === undefined) {\n return undefined;\n }\n return ts.ScriptSnapshot.fromString(diskContent);\n },\n getCurrentDirectory: () => workspaceRoot,\n getCompilationSettings: () => primaryProject.options,\n getDefaultLibFileName: (options) => ts.getDefaultLibFilePath(options),\n fileExists: ts.sys.fileExists,\n readFile: ts.sys.readFile,\n readDirectory: ts.sys.readDirectory,\n directoryExists: ts.sys.directoryExists,\n getDirectories: ts.sys.getDirectories,\n useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames,\n getProjectVersion: () => String(projectVersion),\n resolveModuleNames: (moduleNames, containingFile) => {\n const owningProject = getOwningProject(containingFile);\n\n return moduleNames.map((moduleName) => {\n const ownerResolution = ts.resolveModuleName(\n moduleName,\n containingFile,\n owningProject.options,\n moduleResolutionHost,\n owningProject.moduleResolutionCache,\n ).resolvedModule;\n\n if (ownerResolution) {\n return ownerResolution;\n }\n\n if (owningProject.id === primaryProject.id) {\n return undefined;\n }\n\n return ts.resolveModuleName(\n moduleName,\n containingFile,\n primaryProject.options,\n moduleResolutionHost,\n primaryProject.moduleResolutionCache,\n ).resolvedModule;\n });\n },\n };\n\n const languageService = ts.createLanguageService(host, ts.createDocumentRegistry());\n\n return {\n updateFile(filePath: string, content: string): void {\n const canonicalFilePath = canonicalPath(filePath);\n const currentVersion = inMemoryFiles.get(canonicalFilePath)?.version ?? 0;\n inMemoryFiles.set(canonicalFilePath, {\n version: currentVersion + 1,\n content,\n });\n\n if (!rootFileNames.has(canonicalFilePath)) {\n rootFileNames.add(canonicalFilePath);\n }\n\n projectVersion += 1;\n },\n closeFile(filePath: string): void {\n const canonicalFilePath = canonicalPath(filePath);\n inMemoryFiles.delete(canonicalFilePath);\n projectVersion += 1;\n },\n getProgram(): ts.Program | null {\n return languageService.getProgram() ?? null;\n },\n getSemanticDiagnostics(filePath: string): readonly ts.Diagnostic[] {\n const canonicalFilePath = canonicalPath(filePath);\n return languageService.getSemanticDiagnostics(canonicalFilePath);\n },\n getDefinition(\n filePath: string,\n position: number,\n ): readonly ts.DefinitionInfo[] | undefined {\n const canonicalFilePath = canonicalPath(filePath);\n return languageService.getDefinitionAtPosition(canonicalFilePath, position);\n },\n dispose(): void {\n languageService.dispose();\n },\n };\n}\n\n"],"mappings":"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","names":["realpathSync","statSync","ts","path","realpathSync","canonicalPath","path","realpathSync","ts","realpathSync","statSync"]}
|
|
1
|
+
{"version":3,"sources":["../index.ts","../../../modules/annotation/annotate-file.ts","../../../modules/file-parser/utils.ts","../../../modules/file-parser/walk.ts","../type-analyzer.ts","../../../modules/typescript/workspace-service.ts"],"sourcesContent":["import { realpathSync, statSync } from \"node:fs\";\nimport { relative } from \"node:path\";\n\nimport {\n annotateFile,\n type ElementInfo,\n type PropValue,\n} from \"../../modules/annotation/annotate-file.ts\";\nimport { createFilter, type FilterPattern } from \"@rollup/pluginutils\";\nimport type { Plugin, ResolvedConfig } from \"vite\";\nimport { createTypeAnalyzer, type TypeAnalyzer } from \"./type-analyzer.ts\";\n\nconst DEFAULT_INCLUDE: FilterPattern = [\"**/*.tsx\", \"**/*.jsx\"];\nconst DEFAULT_EXCLUDE: FilterPattern = [\"**/node_modules/**\"];\nconst ROOT_META_NAME = \"tempo-project-root\";\n\nfunction cleanModuleId(id: string): string {\n return id.replace(/[?#].*$/, \"\");\n}\n\nfunction resolveCanonicalRoot(root: string): string {\n try {\n return realpathSync.native(root);\n } catch {\n return root;\n }\n}\n\nfunction hasRootMetaTag(html: string): boolean {\n return /<meta[^>]+name=[\"']tempo-project-root[\"'][^>]*>/i.test(html);\n}\n\nfunction isIntrinsicElement(tagName: string): boolean {\n return tagName.length > 0 && tagName[0] === tagName[0]!.toLowerCase();\n}\n\nfunction defaultComputeAnnotatedProps(\n info: ElementInfo,\n filepath: string,\n modifiedtsMs: number,\n): Record<string, PropValue> {\n return {\n \"data-tempo-filepath\": filepath,\n \"data-tempo-position\": info.element.openingElement.start,\n \"data-tempo-modifiedts\": modifiedtsMs,\n };\n}\n\nexport type ComputeAnnotatedProps = (\n info: ElementInfo,\n filepath: string,\n modifiedtsMs: number,\n) => Record<string, PropValue>;\n\nexport interface TempoAnnotateOptions {\n computeAnnotatedProps?: ComputeAnnotatedProps;\n include?: FilterPattern;\n exclude?: FilterPattern;\n}\n\nexport function tempoAnnotate(options: TempoAnnotateOptions = {}): Plugin {\n // The plugin is a complete no-op unless the TEMPO env var is set.\n // This lets users keep tempoAnnotate() in their vite config permanently\n // while only paying for annotation when running via Tempo's start script\n // (which sets TEMPO=true).\n const enabled = !!process.env.TEMPO;\n\n const include =\n options.include === undefined ? DEFAULT_INCLUDE : options.include;\n const exclude =\n options.exclude === undefined ? DEFAULT_EXCLUDE : options.exclude;\n const filter = createFilter(include, exclude);\n\n const computeAnnotatedProps =\n options.computeAnnotatedProps ?? defaultComputeAnnotatedProps;\n\n let canonicalRoot = process.cwd();\n let command: ResolvedConfig[\"command\"] = \"serve\";\n let typeAnalyzer: TypeAnalyzer | null = null;\n\n return {\n name: \"tempo-annotate\",\n enforce: \"pre\",\n configResolved(resolvedConfig) {\n if (!enabled) return;\n\n command = resolvedConfig.command;\n canonicalRoot = resolveCanonicalRoot(resolvedConfig.root);\n\n if (command === \"serve\") {\n typeAnalyzer = createTypeAnalyzer(canonicalRoot);\n }\n },\n transformIndexHtml(html) {\n if (!enabled || command !== \"serve\") {\n return;\n }\n\n if (hasRootMetaTag(html)) {\n return;\n }\n\n return [\n {\n tag: \"meta\",\n attrs: {\n name: ROOT_META_NAME,\n content: canonicalRoot,\n },\n injectTo: \"head\",\n },\n ];\n },\n transform(source, id) {\n if (!enabled || command === \"build\") {\n return null;\n }\n\n if (id.startsWith(\"\\0\")) {\n return null;\n }\n\n const cleanId = cleanModuleId(id);\n if (!filter(cleanId)) {\n return null;\n }\n\n try {\n const filepath = relative(canonicalRoot, cleanId);\n const modifiedtsMs = Math.trunc(statSync(cleanId).mtimeMs);\n\n const typeInfo = typeAnalyzer?.analyzeFileTypes(cleanId, source);\n\n const result = annotateFile(source, cleanId, (info) => {\n const userProps = computeAnnotatedProps(info, filepath, modifiedtsMs);\n\n // Intrinsic HTML elements always support style and className — no annotation needed\n if (isIntrinsicElement(info.tagName)) {\n return userProps;\n }\n\n // Custom components: look up type support by position, default to false\n const support = typeInfo?.get(info.element.openingElement.start);\n return {\n ...userProps,\n \"data-tempo-supports-style\": support?.supportsStyle ?? false,\n \"data-tempo-supports-classname\":\n support?.supportsClassName ?? false,\n };\n });\n\n if (result.elementsAnnotated === 0) {\n return null;\n }\n\n return {\n code: result.annotatedSource,\n map: null,\n };\n } catch {\n return null;\n }\n },\n };\n}\n\nexport type { ElementInfo, PropValue };\n\nexport type {\n ElementTypeSupport,\n FileTypeInfo,\n TypeAnalyzer,\n} from \"./type-analyzer.ts\";\nexport { createTypeAnalyzer } from \"./type-analyzer.ts\";\n\nexport type {\n TempoPage,\n StoryboardLayout,\n TempoStoryboard,\n TempoRouteStoryboard,\n} from \"./page.ts\";\n","import { parseSync, type JSXElement, type ParseResult } from \"oxc-parser\";\nimport { getTagName } from \"../file-parser/utils.ts\";\nimport { walk } from \"../file-parser/walk.ts\";\n\nexport interface ElementInfo {\n element: JSXElement;\n /** e.g. \"div\", \"Button\", \"Foo.Bar\" */\n tagName: string;\n}\n\n/** Supported prop value types. `undefined` values are skipped. */\nexport type PropValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | ((...args: unknown[]) => unknown)\n | object;\n\nfunction formatPropValue(value: PropValue): string | null {\n if (value === undefined) return null;\n if (typeof value === \"function\") return value.toString();\n return JSON.stringify(value);\n}\n\nfunction formatProps(props: Record<string, PropValue>): string {\n return Object.entries(props)\n .map(([key, value]) => {\n const formatted = formatPropValue(value);\n if (formatted === null) return null;\n return ` ${key}={${formatted}}`;\n })\n .filter((s): s is string => s !== null)\n .join(\"\");\n}\n\nexport interface AnnotateFileResult {\n annotatedSource: string;\n elementsAnnotated: number;\n /** The oxc-parser result. Check `parseResult.errors` for any parse errors. */\n parseResult: ParseResult;\n}\n\n/** Tag names that represent React fragments and should not be annotated */\nconst FRAGMENT_TAG_NAMES = new Set([\"Fragment\", \"React.Fragment\"]);\n\n/**\n * Annotates JSX elements in a source file by inserting additional props.\n *\n * Visits every JSXElement in source order and calls the handler to compute\n * props to insert. Props are inserted at the end of each opening tag.\n *\n * Fragments are skipped since they don't render DOM elements:\n * - JSX shorthand fragments (`<>...</>`) are a separate AST node type\n * - `React.Fragment` and `Fragment` are skipped by tag name\n */\nexport function annotateFile(\n source: string,\n filename: string,\n computeAnnotatedProps: (info: ElementInfo) => Record<string, PropValue>,\n): AnnotateFileResult {\n const parseResult = parseSync(filename, source);\n const insertions: { position: number; text: string }[] = [];\n\n // Walk the AST to find all JSXElement nodes\n // Uses our own walker instead of oxc-parser's Visitor (CJS/ESM interop issue in Electron)\n walk(parseResult.program, {\n JSXElement(node: unknown) {\n const element = node as JSXElement;\n const tagName = getTagName(element.openingElement.name);\n if (FRAGMENT_TAG_NAMES.has(tagName)) return;\n\n const props = computeAnnotatedProps({ element, tagName });\n if (Object.keys(props).length === 0) return;\n\n const openingElement = element.openingElement;\n\n // Insert before \">\" or \"/>\" at end of opening tag, skipping whitespace before \"/>\"\n let insertPos = openingElement.end - 1;\n if (openingElement.selfClosing) {\n insertPos--;\n while (\n insertPos > openingElement.start &&\n /\\s/.test(source[insertPos - 1]!)\n ) {\n insertPos--;\n }\n }\n\n insertions.push({ position: insertPos, text: formatProps(props) });\n },\n });\n\n // Build result in a single pass using chunks (O(n) instead of O(n*m))\n insertions.sort((a, b) => a.position - b.position);\n\n const chunks: string[] = [];\n let lastPos = 0;\n for (const { position, text } of insertions) {\n chunks.push(source.slice(lastPos, position));\n chunks.push(text);\n lastPos = position;\n }\n chunks.push(source.slice(lastPos));\n\n return {\n annotatedSource: chunks.join(\"\"),\n elementsAnnotated: insertions.length,\n parseResult,\n };\n}\n","/**\n * Annotation Utilities\n *\n * Helper functions for working with oxc-parser AST nodes.\n */\n\nimport type { JSXElementName, JSXMemberExpression } from \"oxc-parser\";\n\n/**\n * Extracts the tag name string from any JSXElementName variant.\n *\n * JSXElementName is a union of three types representing different JSX tag syntaxes:\n * - JSXIdentifier: `<button>` → \"button\", `<Button>` → \"Button\"\n * - JSXNamespacedName: `<svg:rect>` → \"svg:rect\" (rare, used in SVG/XML)\n * - JSXMemberExpression: `<Foo.Bar>` → \"Foo.Bar\", `<UI.Button.Primary>` → \"UI.Button.Primary\"\n */\nexport function getTagName(name: JSXElementName): string {\n switch (name.type) {\n case \"JSXIdentifier\":\n return name.name;\n case \"JSXNamespacedName\":\n return `${name.namespace.name}:${name.name.name}`;\n case \"JSXMemberExpression\":\n return getJSXMemberExpressionName(name);\n }\n}\n\n/**\n * Recursively builds the dotted name string from a JSXMemberExpression.\n *\n * JSXMemberExpression represents dotted component names like `<Foo.Bar.Baz>`:\n * - object: either a JSXIdentifier or another JSXMemberExpression (for chaining)\n * - property: always a JSXIdentifier (the rightmost part)\n */\nexport function getJSXMemberExpressionName(node: JSXMemberExpression): string {\n const object =\n node.object.type === \"JSXIdentifier\"\n ? node.object.name\n : getJSXMemberExpressionName(node.object);\n return `${object}.${node.property.name}`;\n}\n","/**\n * AST Walker\n *\n * Simple recursive walker for oxc-parser ASTs. Visits every node in the tree\n * and calls type-specific callbacks. Drop-in replacement for oxc-parser's\n * Visitor class, which has CJS/ESM interop issues in Electron.\n *\n * Once oxc-parser's Visitor works in Electron, this can be swapped back.\n */\n\n/**\n * Callbacks for specific AST node types.\n * Add more node types here as needed.\n */\nexport interface WalkCallbacks {\n JSXElement?: (node: any) => void;\n}\n\n/**\n * Recursively walks an oxc-parser AST, calling callbacks for matching node types.\n * Traverses all object properties and array elements depth-first.\n */\nexport function walk(node: unknown, callbacks: WalkCallbacks): void {\n if (node === null || node === undefined || typeof node !== \"object\") return;\n\n if (Array.isArray(node)) {\n for (const child of node) {\n walk(child, callbacks);\n }\n return;\n }\n\n const record = node as Record<string, unknown>;\n const type = record.type;\n\n if (typeof type === \"string\" && type in callbacks) {\n (callbacks as Record<string, (node: unknown) => void>)[type]!(node);\n }\n\n for (const value of Object.values(record)) {\n if (value !== null && typeof value === \"object\") {\n walk(value, callbacks);\n }\n }\n}\n","/**\n * TypeScript type analyzer for JSX element prop support.\n *\n * Uses a TypeScript Language Service to determine whether each custom React\n * component supports `style` (CSSProperties-compatible) and `className`\n * (string-compatible) props. Correlation between OXC and TypeScript ASTs is\n * position-based — both use UTF-16 string indices, so element positions can\n * be compared directly.\n *\n * Intrinsic HTML elements are excluded from the analysis entirely — the\n * consumer already knows they support both from the HTML standard.\n */\nimport ts from \"typescript\";\nimport path from \"node:path\";\nimport { realpathSync } from \"node:fs\";\nimport {\n createTsWorkspaceService,\n type TsProjectDescriptor,\n type TsWorkspaceService,\n} from \"@modules/typescript\";\n\nexport interface ElementTypeSupport {\n supportsStyle: boolean;\n supportsClassName: boolean;\n}\n\n/** Position → type support for custom components only */\nexport type FileTypeInfo = Map<number, ElementTypeSupport>;\n\nexport interface TypeAnalyzer {\n analyzeFileTypes(filePath: string, source: string): FileTypeInfo | null;\n}\n\n/** Custom component if first character is uppercase or it's a member expression */\nfunction isCustomComponent(node: ts.JsxTagNameExpression): boolean {\n const text = node.getText();\n return text.length > 0 && text[0] !== text[0]!.toLowerCase();\n}\n\ninterface TempobookTsMetadata {\n managedTsconfigPaths?: unknown;\n}\n\nfunction canonicalPath(value: string): string {\n const resolved = path.resolve(value);\n try {\n return realpathSync.native(resolved);\n } catch {\n return resolved;\n }\n}\n\nfunction parseManagedTsconfigPaths(rawConfig: unknown): string[] {\n if (!rawConfig || typeof rawConfig !== \"object\" || Array.isArray(rawConfig)) {\n return [];\n }\n\n const metadata = (rawConfig as { tempobook?: TempobookTsMetadata }).tempobook;\n if (!metadata || typeof metadata !== \"object\" || Array.isArray(metadata)) {\n return [];\n }\n\n const managedPaths = metadata.managedTsconfigPaths;\n if (!Array.isArray(managedPaths)) {\n return [];\n }\n\n return managedPaths.filter(\n (entry): entry is string =>\n typeof entry === \"string\" && entry.trim().length > 0,\n );\n}\n\nfunction parseProjectReferenceTsconfigPaths(\n references: readonly ts.ProjectReference[] | undefined,\n configDir: string,\n): string[] {\n if (!references || references.length === 0) {\n return [];\n }\n\n const entries: string[] = [];\n for (const reference of references) {\n const referencePath = reference.path;\n if (!referencePath) {\n continue;\n }\n\n const resolvedPath = path.resolve(configDir, referencePath);\n const tsconfigPath = resolvedPath.endsWith(\".json\")\n ? resolvedPath\n : path.join(resolvedPath, \"tsconfig.json\");\n\n entries.push(tsconfigPath);\n }\n\n return entries;\n}\n\nfunction buildWorkspaceProjects(\n root: string,\n configPath: string,\n parsedConfig: ts.ParsedCommandLine,\n rawConfig: unknown,\n): TsProjectDescriptor[] {\n const configDir = path.dirname(configPath);\n const projects: TsProjectDescriptor[] = [\n {\n id: \"root\",\n rootDir: root,\n tsconfigPath: configPath,\n priority: 0,\n },\n ];\n\n const seenTsconfigPaths = new Set<string>([canonicalPath(configPath)]);\n const referencedTsconfigPaths = parseProjectReferenceTsconfigPaths(\n parsedConfig.projectReferences,\n configDir,\n );\n const managedTsconfigPaths = parseManagedTsconfigPaths(rawConfig).map(\n (entry) => path.resolve(configDir, entry),\n );\n\n const candidateTsconfigPaths = [\n ...managedTsconfigPaths,\n ...referencedTsconfigPaths,\n ];\n for (const candidatePath of candidateTsconfigPaths) {\n const normalizedPath = canonicalPath(candidatePath);\n if (seenTsconfigPaths.has(normalizedPath)) {\n continue;\n }\n if (!ts.sys.fileExists(normalizedPath)) {\n continue;\n }\n\n seenTsconfigPaths.add(normalizedPath);\n projects.push({\n id: `external-${projects.length}`,\n rootDir: path.dirname(normalizedPath),\n tsconfigPath: normalizedPath,\n priority: 0,\n });\n }\n\n return projects;\n}\n\n/**\n * Create a type analyzer backed by a TypeScript Language Service.\n *\n * The Language Service provides incremental updates — when a file changes,\n * we bump its version and provide the new content. The service lazily\n * recomputes only what's needed.\n *\n * Returns null if no tsconfig.json is found.\n */\nexport function createTypeAnalyzer(root: string): TypeAnalyzer | null {\n const configPath = ts.findConfigFile(\n root,\n ts.sys.fileExists,\n \"tsconfig.json\",\n );\n if (!configPath) return null;\n\n const configFile = ts.readConfigFile(configPath, ts.sys.readFile);\n if (configFile.error) return null;\n\n const parsedConfig = ts.parseJsonConfigFileContent(\n configFile.config,\n ts.sys,\n root,\n );\n\n const workspaceProjects = buildWorkspaceProjects(\n root,\n configPath,\n parsedConfig,\n configFile.config,\n );\n const workspaceProjectRoots = workspaceProjects.map((project) =>\n canonicalPath(project.rootDir),\n );\n\n const workspaceService: TsWorkspaceService = createTsWorkspaceService({\n workspaceRoot: root,\n primaryProjectId: \"root\",\n projects: workspaceProjects,\n });\n\n // Lazily resolved CSSProperties type for style compatibility checks.\n // Resolved from JSX.IntrinsicElements['div'].style, with the undefined\n // union member stripped to get the pure CSSProperties type.\n let cssPropertiesType: ts.Type | null | undefined;\n\n function resolveCSSPropertiesType(\n checker: ts.TypeChecker,\n sourceFile: ts.SourceFile,\n ): ts.Type | null {\n if (cssPropertiesType !== undefined) return cssPropertiesType;\n\n try {\n // JSX namespace → IntrinsicElements → div → style → unwrap undefined\n const jsxNs = (checker as any).resolveName(\n \"JSX\",\n sourceFile,\n ts.SymbolFlags.Namespace,\n false,\n );\n if (!jsxNs) {\n cssPropertiesType = null;\n return null;\n }\n\n const intrinsicSym = checker\n .getExportsOfModule(jsxNs)\n .find((s) => s.name === \"IntrinsicElements\");\n if (!intrinsicSym) {\n cssPropertiesType = null;\n return null;\n }\n\n const divSym = checker\n .getDeclaredTypeOfSymbol(intrinsicSym)\n .getProperty(\"div\");\n if (!divSym) {\n cssPropertiesType = null;\n return null;\n }\n\n const styleSym = checker.getTypeOfSymbol(divSym).getProperty(\"style\");\n if (!styleSym) {\n cssPropertiesType = null;\n return null;\n }\n\n const styleType = checker.getTypeOfSymbol(styleSym);\n\n // styleType is CSSProperties | undefined — extract the non-undefined member\n if (styleType.isUnion()) {\n const nonUndefined = styleType.types.find(\n (t) => !(t.flags & ts.TypeFlags.Undefined),\n );\n cssPropertiesType = nonUndefined ?? null;\n } else {\n cssPropertiesType = styleType;\n }\n } catch {\n cssPropertiesType = null;\n }\n\n return cssPropertiesType;\n }\n\n return {\n analyzeFileTypes(filePath: string, source: string): FileTypeInfo | null {\n const canonicalFilePath = canonicalPath(filePath);\n const belongsToWorkspace = workspaceProjectRoots.some(\n (projectRoot) =>\n canonicalFilePath === projectRoot ||\n canonicalFilePath.startsWith(`${projectRoot}${path.sep}`),\n );\n if (!belongsToWorkspace) {\n return null;\n }\n\n // Update the workspace service with current in-memory source.\n workspaceService.updateFile(filePath, source);\n\n const program = workspaceService.getProgram();\n if (!program) return null;\n\n const sourceFile = program.getSourceFile(filePath);\n if (!sourceFile) return null;\n\n const checker = program.getTypeChecker();\n const cssProps = resolveCSSPropertiesType(checker, sourceFile);\n const result: FileTypeInfo = new Map();\n\n function visit(node: ts.Node) {\n if (\n (ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) &&\n isCustomComponent(node.tagName)\n ) {\n const position = node.getStart(sourceFile);\n const attrsType = checker.getContextualType(node.attributes);\n\n let supportsStyle = false;\n let supportsClassName = false;\n\n if (attrsType) {\n // className: check that `string` is assignable to the prop's type\n const classNameProp = attrsType.getProperty(\"className\");\n if (classNameProp) {\n const propType = checker.getTypeOfSymbol(classNameProp);\n supportsClassName = (checker as any).isTypeAssignableTo(\n checker.getStringType(),\n propType,\n );\n }\n\n // style: check that CSSProperties is assignable to the prop's type\n const styleProp = attrsType.getProperty(\"style\");\n if (styleProp && cssProps) {\n const propType = checker.getTypeOfSymbol(styleProp);\n supportsStyle = (checker as any).isTypeAssignableTo(\n cssProps,\n propType,\n );\n }\n }\n\n result.set(position, { supportsStyle, supportsClassName });\n }\n\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return result;\n },\n };\n}\n","import { realpathSync, statSync } from \"node:fs\";\nimport path from \"node:path\";\n\nimport ts from \"typescript\";\n\nexport interface TsProjectDescriptor {\n id: string;\n rootDir: string;\n tsconfigPath: string;\n priority?: number;\n}\n\nexport interface TsWorkspaceDescriptor {\n workspaceRoot: string;\n projects: TsProjectDescriptor[];\n primaryProjectId?: string;\n}\n\nexport interface TsWorkspaceService {\n updateFile(filePath: string, content: string): void;\n closeFile(filePath: string): void;\n getProgram(): ts.Program | null;\n getSemanticDiagnostics(filePath: string): readonly ts.Diagnostic[];\n getDefinition(\n filePath: string,\n position: number,\n ): readonly ts.DefinitionInfo[] | undefined;\n dispose(): void;\n}\n\ninterface LoadedProject {\n id: string;\n rootDir: string;\n tsconfigPath: string;\n priority: number;\n options: ts.CompilerOptions;\n fileNames: string[];\n moduleResolutionCache: ts.ModuleResolutionCache;\n}\n\ninterface InMemoryFile {\n version: number;\n content: string;\n}\n\nfunction canonicalPath(input: string): string {\n const resolved = path.resolve(input);\n try {\n return realpathSync.native(resolved);\n } catch {\n return resolved;\n }\n}\n\nfunction compareProjectPriority(\n left: LoadedProject,\n right: LoadedProject,\n): number {\n const depthDelta = right.rootDir.length - left.rootDir.length;\n if (depthDelta !== 0) {\n return depthDelta;\n }\n\n const priorityDelta = right.priority - left.priority;\n if (priorityDelta !== 0) {\n return priorityDelta;\n }\n\n return left.id.localeCompare(right.id);\n}\n\nfunction isWithinRoot(filePath: string, rootDir: string): boolean {\n return filePath === rootDir || filePath.startsWith(`${rootDir}${path.sep}`);\n}\n\nfunction loadProject(descriptor: TsProjectDescriptor): LoadedProject {\n const id = descriptor.id.trim();\n if (!id) {\n throw new Error(\"Project id must be a non-empty string\");\n }\n\n const tsconfigPath = canonicalPath(descriptor.tsconfigPath);\n const rootDir = canonicalPath(descriptor.rootDir);\n\n const readResult = ts.readConfigFile(tsconfigPath, ts.sys.readFile);\n if (readResult.error) {\n throw new Error(\n `Failed to read tsconfig at ${tsconfigPath}: ${ts.flattenDiagnosticMessageText(\n readResult.error.messageText,\n \"\\n\",\n )}`,\n );\n }\n\n const parsed = ts.parseJsonConfigFileContent(\n readResult.config,\n ts.sys,\n path.dirname(tsconfigPath),\n );\n\n if (parsed.errors.length > 0) {\n const message = parsed.errors\n .map((diagnostic) =>\n ts.flattenDiagnosticMessageText(diagnostic.messageText, \"\\n\"),\n )\n .join(\"; \");\n throw new Error(`Failed to parse tsconfig at ${tsconfigPath}: ${message}`);\n }\n\n const normalizedFiles = parsed.fileNames.map((fileName) =>\n canonicalPath(fileName),\n );\n return {\n id,\n rootDir,\n tsconfigPath,\n priority: descriptor.priority ?? 0,\n options: parsed.options,\n fileNames: normalizedFiles,\n moduleResolutionCache: ts.createModuleResolutionCache(\n rootDir,\n (value) => value,\n parsed.options,\n ),\n };\n}\n\nfunction getFileMtimeVersion(filePath: string): string {\n try {\n const stats = statSync(filePath);\n return String(stats.mtimeMs);\n } catch {\n return \"0\";\n }\n}\n\nexport function createTsWorkspaceService(\n descriptor: TsWorkspaceDescriptor,\n): TsWorkspaceService {\n if (descriptor.projects.length === 0) {\n throw new Error(\n \"TsWorkspaceDescriptor.projects must include at least one project\",\n );\n }\n\n const workspaceRoot = canonicalPath(descriptor.workspaceRoot);\n const loadedProjects = descriptor.projects.map((project) =>\n loadProject(project),\n );\n\n const projectsById = new Map<string, LoadedProject>();\n for (const project of loadedProjects) {\n if (projectsById.has(project.id)) {\n throw new Error(`Duplicate project id: ${project.id}`);\n }\n projectsById.set(project.id, project);\n }\n\n const primaryProject =\n (descriptor.primaryProjectId\n ? projectsById.get(descriptor.primaryProjectId)\n : null) ?? loadedProjects[0]!;\n if (\n descriptor.primaryProjectId &&\n !projectsById.has(descriptor.primaryProjectId)\n ) {\n throw new Error(\n `Primary project id not found: ${descriptor.primaryProjectId}`,\n );\n }\n\n const orderedProjects = [...loadedProjects].sort(compareProjectPriority);\n const rootFileNames = new Set<string>();\n for (const project of loadedProjects) {\n for (const fileName of project.fileNames) {\n rootFileNames.add(fileName);\n }\n }\n\n const inMemoryFiles = new Map<string, InMemoryFile>();\n let projectVersion = 0;\n\n function getOwningProject(filePath: string): LoadedProject {\n const canonicalFilePath = canonicalPath(filePath);\n for (const project of orderedProjects) {\n if (isWithinRoot(canonicalFilePath, project.rootDir)) {\n return project;\n }\n }\n return primaryProject;\n }\n\n const moduleResolutionHost: ts.ModuleResolutionHost = {\n fileExists: ts.sys.fileExists,\n readFile: ts.sys.readFile,\n realpath: ts.sys.realpath,\n directoryExists: ts.sys.directoryExists,\n getCurrentDirectory: () => workspaceRoot,\n getDirectories: ts.sys.getDirectories,\n };\n\n const host: ts.LanguageServiceHost = {\n getScriptFileNames: () => Array.from(rootFileNames),\n getScriptVersion: (filePath) => {\n const canonicalFilePath = canonicalPath(filePath);\n const inMemory = inMemoryFiles.get(canonicalFilePath);\n if (inMemory) {\n return String(inMemory.version);\n }\n return getFileMtimeVersion(canonicalFilePath);\n },\n getScriptSnapshot: (filePath) => {\n const canonicalFilePath = canonicalPath(filePath);\n const inMemory = inMemoryFiles.get(canonicalFilePath);\n if (inMemory) {\n return ts.ScriptSnapshot.fromString(inMemory.content);\n }\n\n const diskContent = ts.sys.readFile(canonicalFilePath);\n if (diskContent === undefined) {\n return undefined;\n }\n return ts.ScriptSnapshot.fromString(diskContent);\n },\n getCurrentDirectory: () => workspaceRoot,\n getCompilationSettings: () => primaryProject.options,\n getDefaultLibFileName: (options) => ts.getDefaultLibFilePath(options),\n fileExists: ts.sys.fileExists,\n readFile: ts.sys.readFile,\n readDirectory: ts.sys.readDirectory,\n directoryExists: ts.sys.directoryExists,\n getDirectories: ts.sys.getDirectories,\n useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames,\n getProjectVersion: () => String(projectVersion),\n resolveModuleNames: (moduleNames, containingFile) => {\n const owningProject = getOwningProject(containingFile);\n\n return moduleNames.map((moduleName) => {\n const ownerResolution = ts.resolveModuleName(\n moduleName,\n containingFile,\n owningProject.options,\n moduleResolutionHost,\n owningProject.moduleResolutionCache,\n ).resolvedModule;\n\n if (ownerResolution) {\n return ownerResolution;\n }\n\n if (owningProject.id === primaryProject.id) {\n return undefined;\n }\n\n return ts.resolveModuleName(\n moduleName,\n containingFile,\n primaryProject.options,\n moduleResolutionHost,\n primaryProject.moduleResolutionCache,\n ).resolvedModule;\n });\n },\n };\n\n const languageService = ts.createLanguageService(\n host,\n ts.createDocumentRegistry(),\n );\n\n return {\n updateFile(filePath: string, content: string): void {\n const canonicalFilePath = canonicalPath(filePath);\n const currentVersion = inMemoryFiles.get(canonicalFilePath)?.version ?? 0;\n inMemoryFiles.set(canonicalFilePath, {\n version: currentVersion + 1,\n content,\n });\n\n if (!rootFileNames.has(canonicalFilePath)) {\n rootFileNames.add(canonicalFilePath);\n }\n\n projectVersion += 1;\n },\n closeFile(filePath: string): void {\n const canonicalFilePath = canonicalPath(filePath);\n inMemoryFiles.delete(canonicalFilePath);\n projectVersion += 1;\n },\n getProgram(): ts.Program | null {\n return languageService.getProgram() ?? null;\n },\n getSemanticDiagnostics(filePath: string): readonly ts.Diagnostic[] {\n const canonicalFilePath = canonicalPath(filePath);\n return languageService.getSemanticDiagnostics(canonicalFilePath);\n },\n getDefinition(\n filePath: string,\n position: number,\n ): readonly ts.DefinitionInfo[] | undefined {\n const canonicalFilePath = canonicalPath(filePath);\n return languageService.getDefinitionAtPosition(\n canonicalFilePath,\n position,\n );\n },\n dispose(): void {\n languageService.dispose();\n },\n };\n}\n"],"mappings":"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","names":["realpathSync","statSync","ts","path","realpathSync","canonicalPath","path","realpathSync","ts","realpathSync","statSync"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tempo-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Tempo SDK — Vite plugin for JSX annotation and shared page/storyboard types",
|
|
6
6
|
"exports": {
|
|
@@ -9,13 +9,9 @@
|
|
|
9
9
|
"types": "./dist/index.d.ts"
|
|
10
10
|
}
|
|
11
11
|
},
|
|
12
|
-
"files": [
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
"prepublishOnly": "pnpm build",
|
|
16
|
-
"test": "vitest run",
|
|
17
|
-
"test:watch": "vitest"
|
|
18
|
-
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
19
15
|
"dependencies": {
|
|
20
16
|
"@rollup/pluginutils": "^5.1.0",
|
|
21
17
|
"oxc-parser": "^0.110.0"
|
|
@@ -26,14 +22,19 @@
|
|
|
26
22
|
"vite": "^5 || ^6 || ^7"
|
|
27
23
|
},
|
|
28
24
|
"devDependencies": {
|
|
29
|
-
"@modules/annotation": "workspace:*",
|
|
30
|
-
"@modules/typescript": "workspace:*",
|
|
31
25
|
"@types/node": "^25.0.8",
|
|
32
|
-
"@types/react": "
|
|
33
|
-
"@vitejs/plugin-react": "
|
|
26
|
+
"@types/react": "^18.3.17",
|
|
27
|
+
"@vitejs/plugin-react": "^5.1.2",
|
|
34
28
|
"tsup": "^8.5.1",
|
|
35
|
-
"typescript": "
|
|
36
|
-
"vite": "
|
|
37
|
-
"vitest": "
|
|
29
|
+
"typescript": "^5.9.3",
|
|
30
|
+
"vite": "^7.3.1",
|
|
31
|
+
"vitest": "^4.0.18",
|
|
32
|
+
"@modules/annotation": "0.0.1",
|
|
33
|
+
"@modules/typescript": "0.0.1"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsup",
|
|
37
|
+
"test": "vitest run",
|
|
38
|
+
"test:watch": "vitest"
|
|
38
39
|
}
|
|
39
|
-
}
|
|
40
|
+
}
|
package/dist/page.d.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { ComponentType, ComponentProps, ReactElement } from 'react';
|
|
2
|
-
|
|
3
|
-
interface TempoPage {
|
|
4
|
-
name: string;
|
|
5
|
-
}
|
|
6
|
-
interface StoryboardLayout {
|
|
7
|
-
x: number;
|
|
8
|
-
y: number;
|
|
9
|
-
width: number;
|
|
10
|
-
height: number;
|
|
11
|
-
zIndex?: number;
|
|
12
|
-
}
|
|
13
|
-
interface TempoStoryboard<C extends ComponentType<any>> {
|
|
14
|
-
component: C;
|
|
15
|
-
name?: string;
|
|
16
|
-
args?: Partial<ComponentProps<C>>;
|
|
17
|
-
layout: StoryboardLayout;
|
|
18
|
-
container?: (Story: ComponentType<any>) => ReactElement;
|
|
19
|
-
}
|
|
20
|
-
interface TempoRouteStoryboard {
|
|
21
|
-
route: string;
|
|
22
|
-
name?: string;
|
|
23
|
-
layout: StoryboardLayout;
|
|
24
|
-
container?: (Story: ComponentType<any>) => ReactElement;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export type { StoryboardLayout, TempoPage, TempoRouteStoryboard, TempoStoryboard };
|
package/dist/page.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=page.js.map
|
package/dist/page.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|