Skip to content
Draft
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
dbf58c5
Adding empty project for the TypeSpec library.
glecaros Oct 13, 2025
c440fb7
Ported name over to this branch
jpalvarezl Oct 14, 2025
d1e29f3
Added import statements
jpalvarezl Oct 14, 2025
c7b15e5
Added a couple of clarifying remarks
jpalvarezl Oct 14, 2025
fe648d9
Added source-file.tsx
jpalvarezl Oct 14, 2025
0ec982e
Added all the entities in #1
jpalvarezl Oct 14, 2025
f016b14
Added missing imports
jpalvarezl Oct 14, 2025
f4b1e0a
Added model-property too
jpalvarezl Oct 15, 2025
54b2498
Added regex validation for some element names in policy
jpalvarezl Oct 15, 2025
df9cbc4
Adding scopes, symbols and context
jpalvarezl Oct 16, 2025
a9ea352
PR feedback and disabling modelProperty
jpalvarezl Oct 17, 2025
5948676
added namespace-scope for components and moved tests
jpalvarezl Oct 17, 2025
260703d
focusing on namespace.test.tsx at least now the scope is not undefined
jpalvarezl Oct 17, 2025
f5221a1
Added missing JSX
jpalvarezl Oct 17, 2025
e44cf8e
Zoning in the problem
jpalvarezl Oct 17, 2025
321666b
Going down the source-file rabbit hole
jpalvarezl Oct 17, 2025
5e9fe05
Added TestNamespace util
jpalvarezl Oct 17, 2025
b657164
WIP
jpalvarezl Oct 17, 2025
daf16a2
WIP
jpalvarezl Oct 17, 2025
c0639b8
Fixed compilation
jpalvarezl Oct 17, 2025
4f80830
Simplified source just to see if I am able to render something
jpalvarezl Oct 17, 2025
e184200
Add directory.
glecaros Oct 27, 2025
bf121bf
asdf
glecaros Oct 27, 2025
74c06fd
wip
glecaros Oct 27, 2025
a972a51
Merge branch 'feature/typespec' into jpalvarezl/base_context
glecaros Oct 28, 2025
e3b6d51
namespaces!
glecaros Oct 28, 2025
15839e4
PR feedback and cleanup
jpalvarezl Oct 29, 2025
55a5e05
Removed more unnecessary code at this point
jpalvarezl Oct 30, 2025
db7d4ca
WIP: getting namespace as props not working yet
jpalvarezl Oct 30, 2025
8421dee
WIP: still failing but now both failing tests create the namespacesym…
jpalvarezl Oct 30, 2025
b41eada
fixed one more test
jpalvarezl Nov 3, 2025
a9929d4
Consolidated namespaces under single component type
jpalvarezl Nov 3, 2025
6390c62
Removed setting of removed flagged
jpalvarezl Nov 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,5 @@ packages/*/tsdoc-metadata.json
packages/docs/src/content/docs/reference
packages/docs/dist-build

alloy-output/
alloy-output/
.pnpm-store/
4 changes: 4 additions & 0 deletions packages/typespec/api-extractor.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/api-extractor/v7/api-extractor.schema.json",
"extends": "../../api-extractor.base.json"
}
51 changes: 51 additions & 0 deletions packages/typespec/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"name": "@alloy-js/typespec",
"version": "0.1.0",
"description": "",
"exports": {
".": {
"development": "./src/index.ts",
"import": "./dist/src/index.js"
},
"./stc": {
"development": "./src/components/stc/index.ts",
"import": "./dist/src/components/stc/index.js"
},
"./testing": {
"development": "./testing/index.ts",
"import": "./dist/testing/index.js"
}
},
"imports": {
"#components/*": {
"development": "./src/components/*",
"default": "./dist/src/components/*"
}
},
"scripts": {
"generate-docs": "api-extractor run",
"build": "alloy build && pnpm run generate-docs",
"clean": "rimraf dist/ .temp/",
"test:watch": "vitest -w",
"watch": "alloy build --watch",
"test": "vitest run",
"prepack": "node ../../scripts/strip-dev-exports.js"
},
"keywords": [],
"license": "MIT",
"dependencies": {
"@alloy-js/core": "workspace:~",
"change-case": "catalog:",
"pathe": "catalog:"
},
"devDependencies": {
"@alloy-js/cli": "workspace:~",
"@alloy-js/rollup-plugin": "workspace:~",
"@microsoft/api-extractor": "catalog:",
"@rollup/plugin-typescript": "catalog:",
"concurrently": "catalog:",
"typescript": "catalog:",
"vitest": "catalog:"
},
"type": "module"
}
15 changes: 15 additions & 0 deletions packages/typespec/src/components/Reference.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as core from "@alloy-js/core";
import { ref } from "../symbols/reference.js";

export interface ReferenceProps {
refkey: core.Refkey;
}

// used to resolve refkey references within source files
export function Reference({ refkey }: ReferenceProps) {
const reference = ref(refkey);
const symbolRef = core.computed(() => reference()[1]);

core.emitSymbol(symbolRef);
return <>{reference()[0]}</>;
}
5 changes: 5 additions & 0 deletions packages/typespec/src/components/alias.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface AliasProps {};

export function Alias(props: AliasProps) {
return <></>;
}
5 changes: 5 additions & 0 deletions packages/typespec/src/components/decorator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface DecoratorProps {};

export function Decorator(props: DecoratorProps) {
return <></>;
}
19 changes: 19 additions & 0 deletions packages/typespec/src/components/directory/directory.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { expect, it } from "vitest";
import { Directory } from "./directory.jsx";
import { Output, SourceFile } from "@alloy-js/core";

it("defines multiple directories with unique source files", () => {
expect(
<Output>
<Directory path="dir1">
<SourceFile path="file.tsp" filetype="tsp">Content of File1</SourceFile>
</Directory>
<Directory path="dir2">
<SourceFile path="file.tsp" filetype="tsp">Content of File2</SourceFile>
</Directory>
</Output>,
).toRenderTo({
"dir1/file.tsp": `Content of File1`,
"dir2/file.tsp": `Content of File2`,
});
});
18 changes: 18 additions & 0 deletions packages/typespec/src/components/directory/directory.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Children, Scope, SourceDirectory } from "@alloy-js/core";
import { createDirectoryScope } from "../../symbols/factories.js";

export interface DirectoryProps {
path: string;
children?: Children;
};

export function Directory(props: DirectoryProps) {
const scope = createDirectoryScope(props.path);
return (
<SourceDirectory path={props.path}>
<Scope value={scope}>
{props.children}
</Scope>
</SourceDirectory>
);
}
5 changes: 5 additions & 0 deletions packages/typespec/src/components/enum.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface EnumProps {};

export function Enum(props: EnumProps) {
return <></>;
}
5 changes: 5 additions & 0 deletions packages/typespec/src/components/import.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface ImportProps {};

export function Import(props: ImportProps) {
return <></>;
}
14 changes: 14 additions & 0 deletions packages/typespec/src/components/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export * from "./alias.jsx";
export * from "./decorator.jsx";
export * from "./enum.jsx";
export * from "./import.jsx";
export * from "./interface.jsx";
export * from "./model-property.jsx";
export * from "./model.jsx";
export * from "./namespace.jsx";
export * from "./operation.jsx"
export * from "./scalar.jsx";
export * from "./directory/directory.jsx"
export * from "./source-file/source-file.jsx";
export * from "./union.jsx";
export * from "./value.jsx";
5 changes: 5 additions & 0 deletions packages/typespec/src/components/interface.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface InterfaceProps {};

export function Interface(props: InterfaceProps) {
return <></>;
}
18 changes: 18 additions & 0 deletions packages/typespec/src/components/model-property.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Children, createNamedContext, Declaration, Name } from "@alloy-js/core";
import { createPropertySymbol } from "../symbols/factories.js";

export interface ModelPropertyProps {
name: string;
doc?: Children;
};

export function ModelProperty(props: ModelPropertyProps) {
// const symbol = createPropertySymbol(props.name);

// return (
// <Declaration symbol={symbol}>
// <Name />
// </Declaration>
// );
return <></>;
}
5 changes: 5 additions & 0 deletions packages/typespec/src/components/model.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface ModelProps {};

export function Model(props: ModelProps) {
return <></>;
}
48 changes: 48 additions & 0 deletions packages/typespec/src/components/namespace-scopes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Children } from "@alloy-js/core/jsx-runtime";
import { NamespaceSymbol } from "../symbols/namespace.js";
import { createTypeSpecNamespaceScope } from "../scopes/namespace.js";
import { NamespaceContext } from "../contexts/namespace.js";
import { Scope } from "@alloy-js/core";

export interface NamespaceScopeProps {
symbol: NamespaceSymbol;
children: Children;
}

export function NamespaceScope(props: NamespaceScopeProps) {
const scope = createTypeSpecNamespaceScope(props.symbol);
return (
<NamespaceContext.Provider value={{ symbol: props.symbol }}>
<Scope value={scope}>
{props.children}
</Scope>
</NamespaceContext.Provider>
);
}

export interface NamespaceScopesProps {
symbol: NamespaceSymbol;
children: Children;
}

export function NamespaceScopes(props: NamespaceScopesProps) {
function wrapWithScope(symbol: NamespaceSymbol, children: Children) {
const scopeChildren = (
<NamespaceScope symbol={symbol}>
{children}
</NamespaceScope>
);

if (symbol.enclosingNamespace) {
return wrapWithScope(symbol.enclosingNamespace, scopeChildren);
}

return scopeChildren;
}

return (
<NamespaceContext.Provider value={{ symbol: props.symbol }}>
{wrapWithScope(props.symbol, props.children)}
</NamespaceContext.Provider>
);
}
69 changes: 69 additions & 0 deletions packages/typespec/src/components/namespace.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { Block, Children, Namekey, Refkey } from "@alloy-js/core";
import { NamespaceContext, useNamespaceContext } from "../contexts/namespace.js";
import { NamespaceSymbol } from "../symbols/namespace.js";
import { useSourceFileScope } from "../scopes/source-file.js";
import { createNamespaceSymbol } from "../symbols/factories.js";
import { NamespaceScope } from "./namespace-scopes.jsx";

export interface NamespaceProps {
name: string | Namekey | (string | Namekey)[];
refkey?: Refkey | Refkey[];
children?: Children;
};

export function Namespace(props: NamespaceProps) {
const namespaceSymbol = createNamespaceSymbol(props.name, {
refkeys: props.refkey,
});
const sourceFileScope = useSourceFileScope();

if(!sourceFileScope) {
return (
<NamespaceContext.Provider value = {{ symbol: namespaceSymbol }}>
{props.children}
</NamespaceContext.Provider>
);
} else {
// sourceFileScope.hasBlockNamespace = true;

return (
<>
namespace <NamespaceName symbol={namespaceSymbol} relative />{" "}
<Block>
<NamespaceContext.Provider value = {{ symbol: namespaceSymbol }}>
<NamespaceScope symbol={namespaceSymbol}>
{props.children}
</NamespaceScope>
</NamespaceContext.Provider>
</Block>
</>
);
}
}

export interface NamespaceNameProps {
symbol: NamespaceSymbol;

/** If it should print relative to the parent context */
relative? : boolean;
}

export function NamespaceName(props: NamespaceNameProps) {
const names = [props.symbol.name];
const parent = props.relative ? useNamespaceContext()?.symbol : undefined;

let current = props.symbol.ownerSymbol;
while (current) {
if (
current === parent ||
!(current instanceof NamespaceSymbol) ||
current.isGlobal
) {
break;
}
names.unshift(current.name);
current = current.ownerSymbol;
}

return <>{names.join(".")}</>;
}
5 changes: 5 additions & 0 deletions packages/typespec/src/components/operation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface OperationProps {};

export function Operation(props: OperationProps) {
return <></>;
}
5 changes: 5 additions & 0 deletions packages/typespec/src/components/scalar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface ScalarProps {};

export function Scalar(props: ScalarProps) {
return <></>;
}
20 changes: 20 additions & 0 deletions packages/typespec/src/components/source-file/source-file.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { expect, it } from "vitest";
import { Output } from "@alloy-js/core";
import { SourceFile } from "./source-file.jsx";
import { Directory } from "#components/directory/directory.jsx";

it("defines multiple directories with unique source files", () => {
expect(
<Output>
<Directory path="dir1">
<SourceFile path="file.tsp">Content of File1</SourceFile>
</Directory>
<Directory path="dir2">
<SourceFile path="file.tsp">Content of File2</SourceFile>
</Directory>
</Output>,
).toRenderTo({
"dir1/file.tsp": `Content of File1`,
"dir2/file.tsp": `Content of File2`,
});
});
Loading