forked from baron/baron-sso
fix: align local Ory cookie domain rendering
This commit is contained in:
@@ -9,6 +9,9 @@
|
||||
"scripts": {
|
||||
"dev": "vite --host 127.0.0.1",
|
||||
"build": "tsc -b && vite build",
|
||||
"build:org-context-chart": "npm run build:org-context-chart:full && npm run build:org-context-chart:min",
|
||||
"build:org-context-chart:full": "vite build --config vite.org-context-chart.config.ts",
|
||||
"build:org-context-chart:min": "ORG_CONTEXT_CHART_MINIFY=true vite build --config vite.org-context-chart.config.ts",
|
||||
"lint": "biome check .",
|
||||
"preview": "vite preview",
|
||||
"test": "playwright test",
|
||||
|
||||
491
orgfront/src/sdk/org-context-chart/index.ts
Normal file
491
orgfront/src/sdk/org-context-chart/index.ts
Normal file
@@ -0,0 +1,491 @@
|
||||
export type OrgContextMember = {
|
||||
id?: string;
|
||||
email: string;
|
||||
name: string;
|
||||
phone?: string;
|
||||
department?: string;
|
||||
grade?: string;
|
||||
position?: string;
|
||||
jobTitle?: string;
|
||||
isOwner?: boolean;
|
||||
isLeader?: boolean;
|
||||
isPrimary?: boolean;
|
||||
};
|
||||
|
||||
export type OrgContextTenant = {
|
||||
id: string;
|
||||
type: string;
|
||||
name: string;
|
||||
slug: string;
|
||||
parentId?: string | null;
|
||||
status: string;
|
||||
description: string;
|
||||
domains: string[];
|
||||
memberCount: number;
|
||||
visibility: string;
|
||||
orgUnitType?: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
members: OrgContextMember[];
|
||||
};
|
||||
|
||||
export type OrgContextTreeNode = OrgContextTenant & {
|
||||
children: OrgContextTreeNode[];
|
||||
};
|
||||
|
||||
export type OrgContextResponse = {
|
||||
schemaVersion: "baron.org-context.v1";
|
||||
issuedAt: string;
|
||||
scope: {
|
||||
tenantId: string;
|
||||
tenantSlug: string;
|
||||
};
|
||||
tree: OrgContextTreeNode;
|
||||
tenants: OrgContextTenant[];
|
||||
};
|
||||
|
||||
export type OrgChartNode = OrgContextTenant & {
|
||||
children: OrgChartNode[];
|
||||
depth: number;
|
||||
path: string[];
|
||||
};
|
||||
|
||||
export type OrgChartMember = OrgContextMember & {
|
||||
tenantIds: string[];
|
||||
};
|
||||
|
||||
export type OrgChartModel = {
|
||||
root: OrgChartNode;
|
||||
nodes: OrgChartNode[];
|
||||
tenantsById: Map<string, OrgChartNode>;
|
||||
tenantsBySlug: Map<string, OrgChartNode>;
|
||||
membersByEmail: Map<string, OrgChartMember>;
|
||||
response: OrgContextResponse;
|
||||
};
|
||||
|
||||
export type OrgContextClientOptions = {
|
||||
baseUrl: string;
|
||||
credentials?: {
|
||||
keyId: string;
|
||||
keySecret: string;
|
||||
};
|
||||
fetch?: typeof fetch;
|
||||
headers?: Record<string, string>;
|
||||
};
|
||||
|
||||
export type FetchOrgContextOptions = {
|
||||
tenantSlug?: string;
|
||||
includeUsers?: boolean;
|
||||
includeUserIds?: boolean;
|
||||
};
|
||||
|
||||
export type OrgPickerSelection = {
|
||||
id: string;
|
||||
name: string;
|
||||
type: "tenant" | "user";
|
||||
};
|
||||
|
||||
export type OrgPickerOptions = {
|
||||
mode?: "single" | "multiple";
|
||||
selectable?: "tenant" | "user" | "both";
|
||||
includeDescendants?: boolean;
|
||||
onChange?: (selection: OrgPickerSelection[]) => void;
|
||||
};
|
||||
|
||||
export type OrgPickerController = {
|
||||
destroy: () => void;
|
||||
getSelection: () => OrgPickerSelection[];
|
||||
};
|
||||
|
||||
const API_PATH = "/api/v1/integrations/org-context";
|
||||
|
||||
export function createOrgContextClient(options: OrgContextClientOptions) {
|
||||
const fetcher = options.fetch ?? globalThis.fetch;
|
||||
if (!fetcher) {
|
||||
throw new Error("A fetch implementation is required.");
|
||||
}
|
||||
|
||||
return {
|
||||
async fetchOrgContext(
|
||||
query: FetchOrgContextOptions = {},
|
||||
): Promise<OrgContextResponse> {
|
||||
const url = new URL(API_PATH, normalizeBaseUrl(options.baseUrl));
|
||||
appendQuery(url, "tenantSlug", query.tenantSlug);
|
||||
appendQuery(url, "includeUsers", query.includeUsers);
|
||||
appendQuery(url, "includeUserIds", query.includeUserIds);
|
||||
|
||||
const headers: Record<string, string> = {
|
||||
Accept: "application/json",
|
||||
...options.headers,
|
||||
};
|
||||
if (options.credentials) {
|
||||
headers["X-Baron-Key-ID"] = options.credentials.keyId;
|
||||
headers["X-Baron-Key-Secret"] = options.credentials.keySecret;
|
||||
}
|
||||
|
||||
const response = await fetcher(url.toString(), { headers });
|
||||
if (!response.ok) {
|
||||
throw new Error(`Org context request failed with ${response.status}`);
|
||||
}
|
||||
|
||||
const payload = (await response.json()) as OrgContextResponse;
|
||||
if (payload.schemaVersion !== "baron.org-context.v1") {
|
||||
throw new Error(
|
||||
`Unsupported org context schema: ${payload.schemaVersion}`,
|
||||
);
|
||||
}
|
||||
return payload;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function buildOrgChartModel(
|
||||
response: OrgContextResponse,
|
||||
): OrgChartModel {
|
||||
if (response.schemaVersion !== "baron.org-context.v1") {
|
||||
throw new Error(
|
||||
`Unsupported org context schema: ${response.schemaVersion}`,
|
||||
);
|
||||
}
|
||||
|
||||
const nodes: OrgChartNode[] = [];
|
||||
const tenantsById = new Map<string, OrgChartNode>();
|
||||
const tenantsBySlug = new Map<string, OrgChartNode>();
|
||||
const membersByEmail = new Map<string, OrgChartMember>();
|
||||
|
||||
const visit = (
|
||||
node: OrgContextTreeNode,
|
||||
depth: number,
|
||||
ancestorPath: string[],
|
||||
): OrgChartNode => {
|
||||
const path = [...ancestorPath, node.id];
|
||||
const chartNode: OrgChartNode = {
|
||||
...node,
|
||||
children: [],
|
||||
depth,
|
||||
path,
|
||||
};
|
||||
nodes.push(chartNode);
|
||||
tenantsById.set(chartNode.id, chartNode);
|
||||
tenantsBySlug.set(chartNode.slug, chartNode);
|
||||
|
||||
for (const member of chartNode.members) {
|
||||
const key = member.email.toLowerCase();
|
||||
const existing = membersByEmail.get(key);
|
||||
if (existing) {
|
||||
existing.tenantIds.push(chartNode.id);
|
||||
} else {
|
||||
membersByEmail.set(key, {
|
||||
...member,
|
||||
tenantIds: [chartNode.id],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
chartNode.children = node.children.map((child) =>
|
||||
visit(child, depth + 1, path),
|
||||
);
|
||||
return chartNode;
|
||||
};
|
||||
|
||||
return {
|
||||
root: visit(response.tree, 0, []),
|
||||
nodes,
|
||||
tenantsById,
|
||||
tenantsBySlug,
|
||||
membersByEmail,
|
||||
response,
|
||||
};
|
||||
}
|
||||
|
||||
export function renderOrgChart(
|
||||
container: HTMLElement,
|
||||
model: OrgChartModel,
|
||||
): { destroy: () => void } {
|
||||
container.replaceChildren();
|
||||
container.classList.add("baron-org-chart");
|
||||
const root = document.createElement("div");
|
||||
root.className = "baron-org-chart__tree";
|
||||
root.append(renderChartNode(model.root));
|
||||
container.append(root);
|
||||
return {
|
||||
destroy() {
|
||||
container.replaceChildren();
|
||||
container.classList.remove("baron-org-chart");
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function renderOrgPicker(
|
||||
container: HTMLElement,
|
||||
model: OrgChartModel,
|
||||
options: OrgPickerOptions = {},
|
||||
): OrgPickerController {
|
||||
const mode = options.mode ?? "single";
|
||||
const selectable = options.selectable ?? "tenant";
|
||||
const includeDescendants = options.includeDescendants ?? false;
|
||||
const selected = new Map<string, OrgPickerSelection>();
|
||||
|
||||
const emitChange = () => {
|
||||
const selection = Array.from(selected.values());
|
||||
options.onChange?.(selection);
|
||||
container.dispatchEvent(
|
||||
new CustomEvent("baron-org-picker-change", {
|
||||
bubbles: true,
|
||||
detail: { selection },
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
const toggleSelection = (
|
||||
selection: OrgPickerSelection,
|
||||
checked: boolean,
|
||||
descendants: OrgPickerSelection[],
|
||||
) => {
|
||||
if (mode === "single") {
|
||||
selected.clear();
|
||||
if (checked) {
|
||||
selected.set(selectionKey(selection), selection);
|
||||
}
|
||||
emitChange();
|
||||
rerender();
|
||||
return;
|
||||
}
|
||||
|
||||
const targets =
|
||||
includeDescendants && selection.type === "tenant"
|
||||
? [selection, ...descendants]
|
||||
: [selection];
|
||||
for (const target of targets) {
|
||||
if (checked) {
|
||||
selected.set(selectionKey(target), target);
|
||||
} else {
|
||||
selected.delete(selectionKey(target));
|
||||
}
|
||||
}
|
||||
emitChange();
|
||||
rerender();
|
||||
};
|
||||
|
||||
const renderPickerNode = (node: OrgChartNode): HTMLElement => {
|
||||
const item = document.createElement("li");
|
||||
item.className = "baron-org-picker__item";
|
||||
|
||||
const row = document.createElement("label");
|
||||
row.className = "baron-org-picker__row";
|
||||
row.style.paddingLeft = `${node.depth * 16}px`;
|
||||
|
||||
const tenantSelection: OrgPickerSelection = {
|
||||
id: node.id,
|
||||
name: node.name,
|
||||
type: "tenant",
|
||||
};
|
||||
if (selectable === "tenant" || selectable === "both") {
|
||||
row.append(
|
||||
createPickerInput({
|
||||
mode,
|
||||
selection: tenantSelection,
|
||||
selected,
|
||||
onToggle: (checked) =>
|
||||
toggleSelection(
|
||||
tenantSelection,
|
||||
checked,
|
||||
collectDescendantSelections(node, selectable),
|
||||
),
|
||||
}),
|
||||
);
|
||||
}
|
||||
row.append(createLabelText(node.name, node.type));
|
||||
item.append(row);
|
||||
|
||||
if (selectable === "user" || selectable === "both") {
|
||||
for (const member of node.members) {
|
||||
item.append(
|
||||
renderMemberPickerRow(member, node, mode, selected, (value) =>
|
||||
toggleSelection(value, !selected.has(selectionKey(value)), []),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (node.children.length > 0) {
|
||||
const children = document.createElement("ul");
|
||||
children.className = "baron-org-picker__children";
|
||||
for (const child of node.children) {
|
||||
children.append(renderPickerNode(child));
|
||||
}
|
||||
item.append(children);
|
||||
}
|
||||
return item;
|
||||
};
|
||||
|
||||
const rerender = () => {
|
||||
container.replaceChildren();
|
||||
container.classList.add("baron-org-picker");
|
||||
const list = document.createElement("ul");
|
||||
list.className = "baron-org-picker__list";
|
||||
list.append(renderPickerNode(model.root));
|
||||
container.append(list);
|
||||
};
|
||||
|
||||
rerender();
|
||||
|
||||
return {
|
||||
destroy() {
|
||||
container.replaceChildren();
|
||||
container.classList.remove("baron-org-picker");
|
||||
selected.clear();
|
||||
},
|
||||
getSelection() {
|
||||
return Array.from(selected.values());
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function appendQuery(
|
||||
url: URL,
|
||||
key: string,
|
||||
value: string | boolean | undefined,
|
||||
) {
|
||||
if (value !== undefined) {
|
||||
url.searchParams.set(key, String(value));
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeBaseUrl(baseUrl: string) {
|
||||
return baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
|
||||
}
|
||||
|
||||
function renderChartNode(node: OrgChartNode): HTMLElement {
|
||||
const item = document.createElement("section");
|
||||
item.className = "baron-org-chart__node";
|
||||
item.dataset.baronOrgNode = node.id;
|
||||
|
||||
const title = document.createElement("h3");
|
||||
title.className = "baron-org-chart__title";
|
||||
title.textContent = node.name;
|
||||
item.append(title);
|
||||
|
||||
const meta = document.createElement("p");
|
||||
meta.className = "baron-org-chart__meta";
|
||||
meta.textContent = [node.type, node.orgUnitType, node.visibility]
|
||||
.filter(Boolean)
|
||||
.join(" · ");
|
||||
item.append(meta);
|
||||
|
||||
if (node.members.length > 0) {
|
||||
const memberList = document.createElement("ul");
|
||||
memberList.className = "baron-org-chart__members";
|
||||
for (const member of node.members) {
|
||||
const memberItem = document.createElement("li");
|
||||
memberItem.textContent = formatMember(member);
|
||||
memberList.append(memberItem);
|
||||
}
|
||||
item.append(memberList);
|
||||
}
|
||||
|
||||
if (node.children.length > 0) {
|
||||
const children = document.createElement("div");
|
||||
children.className = "baron-org-chart__children";
|
||||
for (const child of node.children) {
|
||||
children.append(renderChartNode(child));
|
||||
}
|
||||
item.append(children);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
function renderMemberPickerRow(
|
||||
member: OrgContextMember,
|
||||
node: OrgChartNode,
|
||||
mode: "single" | "multiple",
|
||||
selected: Map<string, OrgPickerSelection>,
|
||||
onSelect: (selection: OrgPickerSelection) => void,
|
||||
) {
|
||||
const selection: OrgPickerSelection = {
|
||||
id: member.id || `${node.id}:${member.email}`,
|
||||
name: member.name,
|
||||
type: "user",
|
||||
};
|
||||
const row = document.createElement("label");
|
||||
row.className = "baron-org-picker__row baron-org-picker__row--member";
|
||||
row.style.paddingLeft = `${node.depth * 16 + 24}px`;
|
||||
row.append(
|
||||
createPickerInput({
|
||||
mode,
|
||||
selection,
|
||||
selected,
|
||||
onToggle: () => onSelect(selection),
|
||||
}),
|
||||
);
|
||||
row.append(createLabelText(member.name, member.email));
|
||||
return row;
|
||||
}
|
||||
|
||||
function createPickerInput({
|
||||
mode,
|
||||
selection,
|
||||
selected,
|
||||
onToggle,
|
||||
}: {
|
||||
mode: "single" | "multiple";
|
||||
selection: OrgPickerSelection;
|
||||
selected: Map<string, OrgPickerSelection>;
|
||||
onToggle: (checked: boolean) => void;
|
||||
}) {
|
||||
const input = document.createElement("input");
|
||||
input.type = mode === "single" ? "radio" : "checkbox";
|
||||
input.name = "baron-org-picker";
|
||||
input.value = selectionKey(selection);
|
||||
input.checked = selected.has(selectionKey(selection));
|
||||
const handleToggle = () => {
|
||||
onToggle(mode === "single" ? true : !selected.has(selectionKey(selection)));
|
||||
};
|
||||
input.addEventListener("click", handleToggle);
|
||||
return input;
|
||||
}
|
||||
|
||||
function createLabelText(primary: string, secondary?: string) {
|
||||
const text = document.createElement("span");
|
||||
text.className = "baron-org-picker__label";
|
||||
text.textContent = secondary ? `${primary} (${secondary})` : primary;
|
||||
return text;
|
||||
}
|
||||
|
||||
function collectDescendantSelections(
|
||||
node: OrgChartNode,
|
||||
selectable: "tenant" | "user" | "both",
|
||||
): OrgPickerSelection[] {
|
||||
const selections: OrgPickerSelection[] = [];
|
||||
const visit = (child: OrgChartNode) => {
|
||||
if (selectable === "tenant" || selectable === "both") {
|
||||
selections.push({ id: child.id, name: child.name, type: "tenant" });
|
||||
}
|
||||
if (selectable === "user" || selectable === "both") {
|
||||
for (const member of child.members) {
|
||||
selections.push({
|
||||
id: member.id || `${child.id}:${member.email}`,
|
||||
name: member.name,
|
||||
type: "user",
|
||||
});
|
||||
}
|
||||
}
|
||||
for (const grandchild of child.children) {
|
||||
visit(grandchild);
|
||||
}
|
||||
};
|
||||
for (const child of node.children) {
|
||||
visit(child);
|
||||
}
|
||||
return selections;
|
||||
}
|
||||
|
||||
function selectionKey(selection: OrgPickerSelection) {
|
||||
return `${selection.type}:${selection.id}`;
|
||||
}
|
||||
|
||||
function formatMember(member: OrgContextMember) {
|
||||
return [member.name, member.position, member.jobTitle]
|
||||
.filter(Boolean)
|
||||
.join(" · ");
|
||||
}
|
||||
171
orgfront/src/sdk/org-context-chart/orgContextChart.test.ts
Normal file
171
orgfront/src/sdk/org-context-chart/orgContextChart.test.ts
Normal file
@@ -0,0 +1,171 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
type OrgContextResponse,
|
||||
buildOrgChartModel,
|
||||
createOrgContextClient,
|
||||
renderOrgChart,
|
||||
renderOrgPicker,
|
||||
} from "./index";
|
||||
|
||||
const sampleOrgContext: OrgContextResponse = {
|
||||
schemaVersion: "baron.org-context.v1",
|
||||
issuedAt: "2026-05-15T00:00:00Z",
|
||||
scope: {
|
||||
tenantId: "root",
|
||||
tenantSlug: "hanmac-family",
|
||||
},
|
||||
tree: {
|
||||
id: "root",
|
||||
type: "COMPANY_GROUP",
|
||||
name: "한맥가족",
|
||||
slug: "hanmac-family",
|
||||
status: "active",
|
||||
description: "",
|
||||
domains: [],
|
||||
memberCount: 0,
|
||||
visibility: "public",
|
||||
createdAt: "2026-05-15T00:00:00Z",
|
||||
updatedAt: "2026-05-15T00:00:00Z",
|
||||
members: [],
|
||||
children: [
|
||||
{
|
||||
id: "company-baron",
|
||||
type: "COMPANY",
|
||||
name: "Baron",
|
||||
slug: "baron",
|
||||
parentId: "root",
|
||||
status: "active",
|
||||
description: "",
|
||||
domains: ["baron.example"],
|
||||
memberCount: 1,
|
||||
visibility: "public",
|
||||
createdAt: "2026-05-15T00:00:00Z",
|
||||
updatedAt: "2026-05-15T00:00:00Z",
|
||||
members: [
|
||||
{
|
||||
email: "leader@example.com",
|
||||
name: "Leader",
|
||||
grade: "책임",
|
||||
position: "팀장",
|
||||
isLeader: true,
|
||||
isOwner: true,
|
||||
isPrimary: true,
|
||||
},
|
||||
],
|
||||
children: [
|
||||
{
|
||||
id: "team-platform",
|
||||
type: "USER_GROUP",
|
||||
name: "Platform",
|
||||
slug: "platform",
|
||||
parentId: "company-baron",
|
||||
status: "active",
|
||||
description: "",
|
||||
domains: [],
|
||||
memberCount: 1,
|
||||
visibility: "internal",
|
||||
orgUnitType: "팀",
|
||||
createdAt: "2026-05-15T00:00:00Z",
|
||||
updatedAt: "2026-05-15T00:00:00Z",
|
||||
members: [
|
||||
{
|
||||
email: "engineer@example.com",
|
||||
name: "Engineer",
|
||||
jobTitle: "Frontend Engineer",
|
||||
isLeader: false,
|
||||
isOwner: false,
|
||||
isPrimary: false,
|
||||
},
|
||||
],
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
tenants: [],
|
||||
};
|
||||
|
||||
describe("org-context chart SDK", () => {
|
||||
it("builds chart and lookup models from org-context v1", () => {
|
||||
const model = buildOrgChartModel(sampleOrgContext);
|
||||
|
||||
expect(model.root.name).toBe("한맥가족");
|
||||
expect(model.nodes).toHaveLength(3);
|
||||
expect(model.tenantsBySlug.get("platform")?.orgUnitType).toBe("팀");
|
||||
expect(model.membersByEmail.get("engineer@example.com")?.tenantIds).toEqual(
|
||||
["team-platform"],
|
||||
);
|
||||
});
|
||||
|
||||
it("fetches org-context through authenticated API headers", async () => {
|
||||
const fetcher = vi.fn(async () => {
|
||||
return new Response(JSON.stringify(sampleOrgContext), {
|
||||
headers: { "content-type": "application/json" },
|
||||
status: 200,
|
||||
});
|
||||
});
|
||||
const client = createOrgContextClient({
|
||||
baseUrl: "https://sso.example.com",
|
||||
credentials: {
|
||||
keyId: "client-id",
|
||||
keySecret: "client-secret",
|
||||
},
|
||||
fetch: fetcher,
|
||||
});
|
||||
|
||||
await client.fetchOrgContext({
|
||||
tenantSlug: "baron",
|
||||
includeUsers: true,
|
||||
includeUserIds: false,
|
||||
});
|
||||
|
||||
const [url, init] = fetcher.mock.calls[0];
|
||||
expect(String(url)).toBe(
|
||||
"https://sso.example.com/api/v1/integrations/org-context?tenantSlug=baron&includeUsers=true&includeUserIds=false",
|
||||
);
|
||||
expect(init.headers).toMatchObject({
|
||||
"X-Baron-Key-ID": "client-id",
|
||||
"X-Baron-Key-Secret": "client-secret",
|
||||
});
|
||||
});
|
||||
|
||||
it("renders chart and picker DOM with selection events", () => {
|
||||
const model = buildOrgChartModel(sampleOrgContext);
|
||||
const chartContainer = document.createElement("div");
|
||||
const pickerContainer = document.createElement("div");
|
||||
const onChange = vi.fn();
|
||||
|
||||
renderOrgChart(chartContainer, model);
|
||||
const picker = renderOrgPicker(pickerContainer, model, {
|
||||
mode: "multiple",
|
||||
selectable: "both",
|
||||
onChange,
|
||||
});
|
||||
|
||||
expect(
|
||||
chartContainer.querySelectorAll("[data-baron-org-node]"),
|
||||
).toHaveLength(3);
|
||||
const platformCheckbox = pickerContainer.querySelector<HTMLInputElement>(
|
||||
'input[value="tenant:team-platform"]',
|
||||
);
|
||||
expect(platformCheckbox).not.toBeNull();
|
||||
|
||||
platformCheckbox?.click();
|
||||
|
||||
expect(picker.getSelection()).toEqual([
|
||||
{
|
||||
id: "team-platform",
|
||||
name: "Platform",
|
||||
type: "tenant",
|
||||
},
|
||||
]);
|
||||
expect(onChange).toHaveBeenCalledWith([
|
||||
{
|
||||
id: "team-platform",
|
||||
name: "Platform",
|
||||
type: "tenant",
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
@@ -22,5 +22,5 @@
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
"include": ["vite.config.ts", "vite.org-context-chart.config.ts"]
|
||||
}
|
||||
|
||||
25
orgfront/vite.org-context-chart.config.ts
Normal file
25
orgfront/vite.org-context-chart.config.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { defineConfig } from "vite";
|
||||
|
||||
const isMinifiedBuild = process.env.ORG_CONTEXT_CHART_MINIFY === "true";
|
||||
const fileSuffix = isMinifiedBuild ? ".min" : "";
|
||||
|
||||
export default defineConfig({
|
||||
build: {
|
||||
emptyOutDir: !isMinifiedBuild,
|
||||
lib: {
|
||||
entry: fileURLToPath(
|
||||
new URL("./src/sdk/org-context-chart/index.ts", import.meta.url),
|
||||
),
|
||||
fileName: (format) =>
|
||||
format === "es"
|
||||
? `baron-org-context-chart${fileSuffix}.js`
|
||||
: `baron-org-context-chart${fileSuffix}.umd.cjs`,
|
||||
formats: ["es", "umd"],
|
||||
name: "BaronOrgContextChart",
|
||||
},
|
||||
minify: isMinifiedBuild,
|
||||
outDir: "dist/org-context-chart",
|
||||
sourcemap: true,
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user