@eventcatalog/core 3.43.0 → 3.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/analytics/analytics.cjs +1 -1
  2. package/dist/analytics/analytics.js +2 -2
  3. package/dist/analytics/log-build.cjs +50 -2
  4. package/dist/analytics/log-build.js +4 -4
  5. package/dist/catalog-to-astro-content-directory.cjs +31 -1
  6. package/dist/catalog-to-astro-content-directory.js +2 -2
  7. package/dist/{chunk-O6KT4DPL.js → chunk-4SMA4HQ3.js} +1 -1
  8. package/dist/{chunk-5T63CXKU.js → chunk-6QENHZZP.js} +32 -2
  9. package/dist/{chunk-ZQHBDPIY.js → chunk-A7WJATRV.js} +2 -2
  10. package/dist/{chunk-ULZYHF3V.js → chunk-B7HCX5HM.js} +1 -1
  11. package/dist/{chunk-2EI3M7OO.js → chunk-H7IGB2WO.js} +1 -1
  12. package/dist/{chunk-7M5IQL3J.js → chunk-L2JZBH6K.js} +1 -1
  13. package/dist/{chunk-WAJIJEI3.js → chunk-LHR4G2UO.js} +1 -1
  14. package/dist/{chunk-QV2PKXZM.js → chunk-SWSSBJ6H.js} +20 -2
  15. package/dist/{chunk-KY74BE42.js → chunk-W7UIDHNR.js} +1 -1
  16. package/dist/constants.cjs +1 -1
  17. package/dist/constants.js +1 -1
  18. package/dist/eventcatalog-config-file-utils.cjs +31 -1
  19. package/dist/eventcatalog-config-file-utils.js +1 -1
  20. package/dist/eventcatalog.cjs +50 -2
  21. package/dist/eventcatalog.config.d.cts +25 -0
  22. package/dist/eventcatalog.config.d.ts +25 -0
  23. package/dist/eventcatalog.js +9 -9
  24. package/dist/features.cjs +31 -1
  25. package/dist/features.js +2 -2
  26. package/dist/generate.cjs +32 -2
  27. package/dist/generate.js +4 -4
  28. package/dist/resolve-catalog-dependencies.cjs +31 -1
  29. package/dist/resolve-catalog-dependencies.js +2 -2
  30. package/dist/utils/cli-logger.cjs +1 -1
  31. package/dist/utils/cli-logger.js +2 -2
  32. package/eventcatalog/astro.config.mjs +9 -1
  33. package/eventcatalog/src/components/FieldsExplorer/FieldNodeGraph.tsx +2 -2
  34. package/eventcatalog/src/components/Tables/Table.tsx +4 -0
  35. package/eventcatalog/src/components/Tables/columns/DirectorySourceColumn.tsx +49 -0
  36. package/eventcatalog/src/components/Tables/columns/TeamsTableColumns.tsx +11 -0
  37. package/eventcatalog/src/components/Tables/columns/UserTableColumns.tsx +11 -0
  38. package/eventcatalog/src/content.config.ts +29 -8
  39. package/eventcatalog/src/enterprise/directory/user-team-directory.spec.ts +527 -0
  40. package/eventcatalog/src/enterprise/directory/user-team-directory.ts +191 -0
  41. package/eventcatalog/src/pages/directory/[type]/index.astro +2 -0
  42. package/eventcatalog/src/pages/docs/teams/[id]/index.astro +29 -5
  43. package/eventcatalog/src/pages/docs/users/[id]/index.astro +29 -0
  44. package/eventcatalog/src/stores/eventcatalog-store.spec.ts +60 -0
  45. package/eventcatalog/src/stores/eventcatalog-store.ts +103 -0
  46. package/package.json +3 -3
package/dist/features.cjs CHANGED
@@ -51,6 +51,36 @@ async function cleanup(projectDirectory) {
51
51
  await (0, import_promises.rm)(filePath);
52
52
  }
53
53
  }
54
+ var findNodeModulesDirectory = (directory) => {
55
+ let currentDirectory = directory;
56
+ while (true) {
57
+ const nodeModulesDirectory = import_node_path.default.join(currentDirectory, "node_modules");
58
+ if ((0, import_node_fs.existsSync)(nodeModulesDirectory)) {
59
+ return nodeModulesDirectory;
60
+ }
61
+ const parentDirectory = import_node_path.default.dirname(currentDirectory);
62
+ if (parentDirectory === currentDirectory) {
63
+ return void 0;
64
+ }
65
+ currentDirectory = parentDirectory;
66
+ }
67
+ };
68
+ var linkNodeModulesIntoTempDirectory = async ({ projectDirectory, tempDir }) => {
69
+ const nodeModulesDirectory = findNodeModulesDirectory(projectDirectory);
70
+ if (!nodeModulesDirectory) {
71
+ return;
72
+ }
73
+ await (0, import_promises.symlink)(nodeModulesDirectory, import_node_path.default.join(tempDir, "node_modules"), "dir");
74
+ };
75
+ var createTemporaryConfigDirectory = async (projectDirectory) => {
76
+ const nodeModulesDirectory = findNodeModulesDirectory(projectDirectory);
77
+ if (nodeModulesDirectory) {
78
+ return (0, import_promises.mkdtemp)(import_node_path.default.join(nodeModulesDirectory, ".eventcatalog-config-"));
79
+ }
80
+ const tempDir = await (0, import_promises.mkdtemp)(import_node_path.default.join((0, import_node_os.tmpdir)(), "eventcatalog-config-"));
81
+ await linkNodeModulesIntoTempDirectory({ projectDirectory, tempDir });
82
+ return tempDir;
83
+ };
54
84
  var getEventCatalogConfigFile = async (projectDirectory) => {
55
85
  let tempDir;
56
86
  try {
@@ -58,7 +88,7 @@ var getEventCatalogConfigFile = async (projectDirectory) => {
58
88
  const filePath = import_node_path.default.join(projectDirectory, "package.json");
59
89
  const packageJson = JSON.parse(await (0, import_promises.readFile)(filePath, "utf-8"));
60
90
  if (packageJson?.type !== "module") {
61
- tempDir = await (0, import_promises.mkdtemp)(import_node_path.default.join((0, import_node_os.tmpdir)(), "eventcatalog-config-"));
91
+ tempDir = await createTemporaryConfigDirectory(projectDirectory);
62
92
  configFilePath = import_node_path.default.join(tempDir, "eventcatalog.config.mjs");
63
93
  await (0, import_promises.copyFile)(import_node_path.default.join(projectDirectory, "eventcatalog.config.js"), configFilePath);
64
94
  }
package/dist/features.js CHANGED
@@ -3,8 +3,8 @@ import {
3
3
  isAuthEnabled,
4
4
  isIndexedSearchEnabled,
5
5
  isOutputServer
6
- } from "./chunk-ULZYHF3V.js";
7
- import "./chunk-5T63CXKU.js";
6
+ } from "./chunk-B7HCX5HM.js";
7
+ import "./chunk-6QENHZZP.js";
8
8
  export {
9
9
  getProjectOutDir,
10
10
  isAuthEnabled,
package/dist/generate.cjs CHANGED
@@ -49,6 +49,36 @@ async function cleanup(projectDirectory) {
49
49
  await (0, import_promises.rm)(filePath);
50
50
  }
51
51
  }
52
+ var findNodeModulesDirectory = (directory) => {
53
+ let currentDirectory = directory;
54
+ while (true) {
55
+ const nodeModulesDirectory = import_node_path.default.join(currentDirectory, "node_modules");
56
+ if ((0, import_node_fs.existsSync)(nodeModulesDirectory)) {
57
+ return nodeModulesDirectory;
58
+ }
59
+ const parentDirectory = import_node_path.default.dirname(currentDirectory);
60
+ if (parentDirectory === currentDirectory) {
61
+ return void 0;
62
+ }
63
+ currentDirectory = parentDirectory;
64
+ }
65
+ };
66
+ var linkNodeModulesIntoTempDirectory = async ({ projectDirectory, tempDir }) => {
67
+ const nodeModulesDirectory = findNodeModulesDirectory(projectDirectory);
68
+ if (!nodeModulesDirectory) {
69
+ return;
70
+ }
71
+ await (0, import_promises.symlink)(nodeModulesDirectory, import_node_path.default.join(tempDir, "node_modules"), "dir");
72
+ };
73
+ var createTemporaryConfigDirectory = async (projectDirectory) => {
74
+ const nodeModulesDirectory = findNodeModulesDirectory(projectDirectory);
75
+ if (nodeModulesDirectory) {
76
+ return (0, import_promises.mkdtemp)(import_node_path.default.join(nodeModulesDirectory, ".eventcatalog-config-"));
77
+ }
78
+ const tempDir = await (0, import_promises.mkdtemp)(import_node_path.default.join((0, import_node_os.tmpdir)(), "eventcatalog-config-"));
79
+ await linkNodeModulesIntoTempDirectory({ projectDirectory, tempDir });
80
+ return tempDir;
81
+ };
52
82
  var getEventCatalogConfigFile = async (projectDirectory) => {
53
83
  let tempDir;
54
84
  try {
@@ -56,7 +86,7 @@ var getEventCatalogConfigFile = async (projectDirectory) => {
56
86
  const filePath = import_node_path.default.join(projectDirectory, "package.json");
57
87
  const packageJson = JSON.parse(await (0, import_promises.readFile)(filePath, "utf-8"));
58
88
  if (packageJson?.type !== "module") {
59
- tempDir = await (0, import_promises.mkdtemp)(import_node_path.default.join((0, import_node_os.tmpdir)(), "eventcatalog-config-"));
89
+ tempDir = await createTemporaryConfigDirectory(projectDirectory);
60
90
  configFilePath = import_node_path.default.join(tempDir, "eventcatalog.config.mjs");
61
91
  await (0, import_promises.copyFile)(import_node_path.default.join(projectDirectory, "eventcatalog.config.js"), configFilePath);
62
92
  }
@@ -78,7 +108,7 @@ var getEventCatalogConfigFile = async (projectDirectory) => {
78
108
  var import_picocolors = __toESM(require("picocolors"), 1);
79
109
 
80
110
  // package.json
81
- var version = "3.43.0";
111
+ var version = "3.44.0";
82
112
 
83
113
  // src/constants.ts
84
114
  var VERSION = version;
package/dist/generate.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  generate
3
- } from "./chunk-ZQHBDPIY.js";
4
- import "./chunk-7M5IQL3J.js";
5
- import "./chunk-KY74BE42.js";
6
- import "./chunk-5T63CXKU.js";
3
+ } from "./chunk-A7WJATRV.js";
4
+ import "./chunk-L2JZBH6K.js";
5
+ import "./chunk-W7UIDHNR.js";
6
+ import "./chunk-6QENHZZP.js";
7
7
  export {
8
8
  generate
9
9
  };
@@ -48,6 +48,36 @@ async function cleanup(projectDirectory) {
48
48
  await (0, import_promises.rm)(filePath);
49
49
  }
50
50
  }
51
+ var findNodeModulesDirectory = (directory) => {
52
+ let currentDirectory = directory;
53
+ while (true) {
54
+ const nodeModulesDirectory = import_node_path.default.join(currentDirectory, "node_modules");
55
+ if ((0, import_node_fs.existsSync)(nodeModulesDirectory)) {
56
+ return nodeModulesDirectory;
57
+ }
58
+ const parentDirectory = import_node_path.default.dirname(currentDirectory);
59
+ if (parentDirectory === currentDirectory) {
60
+ return void 0;
61
+ }
62
+ currentDirectory = parentDirectory;
63
+ }
64
+ };
65
+ var linkNodeModulesIntoTempDirectory = async ({ projectDirectory, tempDir }) => {
66
+ const nodeModulesDirectory = findNodeModulesDirectory(projectDirectory);
67
+ if (!nodeModulesDirectory) {
68
+ return;
69
+ }
70
+ await (0, import_promises.symlink)(nodeModulesDirectory, import_node_path.default.join(tempDir, "node_modules"), "dir");
71
+ };
72
+ var createTemporaryConfigDirectory = async (projectDirectory) => {
73
+ const nodeModulesDirectory = findNodeModulesDirectory(projectDirectory);
74
+ if (nodeModulesDirectory) {
75
+ return (0, import_promises.mkdtemp)(import_node_path.default.join(nodeModulesDirectory, ".eventcatalog-config-"));
76
+ }
77
+ const tempDir = await (0, import_promises.mkdtemp)(import_node_path.default.join((0, import_node_os.tmpdir)(), "eventcatalog-config-"));
78
+ await linkNodeModulesIntoTempDirectory({ projectDirectory, tempDir });
79
+ return tempDir;
80
+ };
51
81
  var getEventCatalogConfigFile = async (projectDirectory) => {
52
82
  let tempDir;
53
83
  try {
@@ -55,7 +85,7 @@ var getEventCatalogConfigFile = async (projectDirectory) => {
55
85
  const filePath = import_node_path.default.join(projectDirectory, "package.json");
56
86
  const packageJson = JSON.parse(await (0, import_promises.readFile)(filePath, "utf-8"));
57
87
  if (packageJson?.type !== "module") {
58
- tempDir = await (0, import_promises.mkdtemp)(import_node_path.default.join((0, import_node_os.tmpdir)(), "eventcatalog-config-"));
88
+ tempDir = await createTemporaryConfigDirectory(projectDirectory);
59
89
  configFilePath = import_node_path.default.join(tempDir, "eventcatalog.config.mjs");
60
90
  await (0, import_promises.copyFile)(import_node_path.default.join(projectDirectory, "eventcatalog.config.js"), configFilePath);
61
91
  }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  resolve_catalog_dependencies_default
3
- } from "./chunk-WAJIJEI3.js";
4
- import "./chunk-5T63CXKU.js";
3
+ } from "./chunk-LHR4G2UO.js";
4
+ import "./chunk-6QENHZZP.js";
5
5
  export {
6
6
  resolve_catalog_dependencies_default as default
7
7
  };
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(cli_logger_exports);
36
36
  var import_picocolors = __toESM(require("picocolors"), 1);
37
37
 
38
38
  // package.json
39
- var version = "3.43.0";
39
+ var version = "3.44.0";
40
40
 
41
41
  // src/constants.ts
42
42
  var VERSION = version;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  logger
3
- } from "../chunk-7M5IQL3J.js";
4
- import "../chunk-KY74BE42.js";
3
+ } from "../chunk-L2JZBH6K.js";
4
+ import "../chunk-W7UIDHNR.js";
5
5
  export {
6
6
  logger
7
7
  };
@@ -37,6 +37,9 @@ const expressiveCodeConfig = {
37
37
  },
38
38
  };
39
39
 
40
+ const markdownRemarkPlugins = [remarkDirective, remarkDirectives, remarkComment, mermaid, plantuml];
41
+ const mdxRemarkPlugins = [...markdownRemarkPlugins, remarkResourceRef];
42
+
40
43
  // https://astro.build/config
41
44
  export default defineConfig({
42
45
  base,
@@ -66,6 +69,11 @@ export default defineConfig({
66
69
  // https://docs.astro.build/en/reference/configuration-reference/#trailingslash
67
70
  trailingSlash: config.trailingSlash === true ? 'always' : 'ignore',
68
71
 
72
+ markdown: {
73
+ remarkPlugins: markdownRemarkPlugins,
74
+ gfm: true,
75
+ },
76
+
69
77
  // just turn this off for all users (for now...)
70
78
  devToolbar: { enabled: false },
71
79
  integrations: [
@@ -76,7 +84,7 @@ export default defineConfig({
76
84
  mdx({
77
85
  // https://docs.astro.build/en/guides/integrations-guide/mdx/#optimize
78
86
  optimize: config.mdxOptimize || false,
79
- remarkPlugins: [remarkDirective, remarkDirectives, remarkComment, mermaid, plantuml, remarkResourceRef],
87
+ remarkPlugins: mdxRemarkPlugins,
80
88
  rehypePlugins: [
81
89
  [
82
90
  rehypeExpressiveCode,
@@ -15,8 +15,8 @@ import {
15
15
  Event as EventNodeComponent,
16
16
  Command as CommandNodeComponent,
17
17
  Query as QueryNodeComponent,
18
- Service as ServiceNodeComponent,
19
18
  Field as FieldNodeComponent,
19
+ nodeComponents,
20
20
  } from '@eventcatalog/visualiser';
21
21
  import { X, ChevronDown, ChevronRight, Search, AlertTriangle } from 'lucide-react';
22
22
  import { BoltIcon, ChatBubbleLeftIcon, MagnifyingGlassIcon, ServerIcon } from '@heroicons/react/24/solid';
@@ -88,7 +88,7 @@ function wrapWithContextMenu(Component: React.ComponentType<any>) {
88
88
  // and the catalog means these MemoExoticComponents don't match ComponentType<any>
89
89
  // unless we widen once here.
90
90
  const nodeTypes = {
91
- service: wrapWithContextMenu(ServiceNodeComponent as unknown as React.ComponentType<any>),
91
+ service: wrapWithContextMenu(nodeComponents.service as unknown as React.ComponentType<any>),
92
92
  event: wrapWithContextMenu(EventNodeComponent as unknown as React.ComponentType<any>),
93
93
  command: wrapWithContextMenu(CommandNodeComponent as unknown as React.ComponentType<any>),
94
94
  query: wrapWithContextMenu(QueryNodeComponent as unknown as React.ComponentType<any>),
@@ -51,6 +51,10 @@ export type TData<T extends TCollectionTypes> = {
51
51
  name: string;
52
52
  summary: string;
53
53
  version: string;
54
+ source?: {
55
+ provider: string;
56
+ url?: string;
57
+ };
54
58
  latestVersion?: string; // Defined on getter collection utility
55
59
  draft?: boolean | { title?: string; message: string }; // Draft property from base schema
56
60
  badges?: Array<{
@@ -0,0 +1,49 @@
1
+ import { FileText, Github } from 'lucide-react';
2
+
3
+ type DirectorySource = {
4
+ provider: string;
5
+ url?: string;
6
+ };
7
+
8
+ export const DirectorySourceCell = ({ source }: { source?: DirectorySource }) => {
9
+ if (source?.provider === 'github') {
10
+ const icon = (
11
+ <Github className="h-4 w-4 text-[rgb(var(--ec-icon-color))] transition-colors group-hover/source:text-[rgb(var(--ec-page-text))]" />
12
+ );
13
+
14
+ if (source.url) {
15
+ return (
16
+ <a
17
+ href={source.url}
18
+ target="_blank"
19
+ rel="noreferrer"
20
+ className="group/source inline-flex h-7 w-7 items-center justify-center rounded-md border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-page-bg)/0.35)] transition-colors hover:bg-[rgb(var(--ec-content-hover))]"
21
+ title="Synced from GitHub"
22
+ aria-label="Synced from GitHub"
23
+ >
24
+ {icon}
25
+ </a>
26
+ );
27
+ }
28
+
29
+ return (
30
+ <span
31
+ className="inline-flex h-7 w-7 items-center justify-center rounded-md border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-page-bg)/0.35)]"
32
+ title="Synced from GitHub"
33
+ aria-label="Synced from GitHub"
34
+ >
35
+ {icon}
36
+ </span>
37
+ );
38
+ }
39
+
40
+ return (
41
+ <span
42
+ className="inline-flex h-7 w-7 items-center justify-center rounded-md border border-[rgb(var(--ec-page-border))] bg-[rgb(var(--ec-page-bg)/0.35)] text-[rgb(var(--ec-icon-color))]"
43
+ title="Synced to local file"
44
+ aria-label="Synced to local file"
45
+ >
46
+ <FileText className="h-4 w-4" />
47
+ </span>
48
+ );
49
+ };
@@ -7,6 +7,7 @@ import type { CollectionUserTypes } from '@types';
7
7
  import type { TableConfiguration } from '@types';
8
8
  import { getColorAndIconForCollection } from '@utils/collections/icons';
9
9
  import { getCollectionTextColorClass } from '@utils/collection-colors';
10
+ import { DirectorySourceCell } from './DirectorySourceColumn';
10
11
  const columnHelper = createColumnHelper<TData<CollectionUserTypes>>();
11
12
 
12
13
  const CollectionListCell = ({
@@ -81,6 +82,16 @@ export const columns = (tableConfiguration: TableConfiguration) => [
81
82
  filterFn: filterByName,
82
83
  }),
83
84
 
85
+ columnHelper.accessor('data.source', {
86
+ id: 'source',
87
+ header: () => <span>{tableConfiguration.columns?.source?.label || 'Source'}</span>,
88
+ cell: (info) => <DirectorySourceCell source={info.getValue() as { provider: string; url?: string } | undefined} />,
89
+ meta: {
90
+ showFilter: false,
91
+ className: 'w-[96px]',
92
+ },
93
+ }),
94
+
84
95
  columnHelper.accessor(
85
96
  (row) => {
86
97
  const events = row.data.ownedEvents || [];
@@ -7,6 +7,7 @@ import type { CollectionUserTypes } from '@types';
7
7
  import type { TableConfiguration } from '@types';
8
8
  import { getColorAndIconForCollection } from '@utils/collections/icons';
9
9
  import { getCollectionTextColorClass } from '@utils/collection-colors';
10
+ import { DirectorySourceCell } from './DirectorySourceColumn';
10
11
  const columnHelper = createColumnHelper<TData<CollectionUserTypes>>();
11
12
 
12
13
  const CollectionListCell = ({
@@ -84,6 +85,16 @@ export const columns = (tableConfiguration: TableConfiguration) => [
84
85
  filterFn: filterByName,
85
86
  }),
86
87
 
88
+ columnHelper.accessor('data.source', {
89
+ id: 'source',
90
+ header: () => <span>{tableConfiguration.columns?.source?.label || 'Source'}</span>,
91
+ cell: (info) => <DirectorySourceCell source={info.getValue() as { provider: string; url?: string } | undefined} />,
92
+ meta: {
93
+ showFilter: false,
94
+ className: 'w-[96px]',
95
+ },
96
+ }),
97
+
87
98
  columnHelper.accessor('data.role', {
88
99
  id: 'role',
89
100
  header: () => <span>{tableConfiguration.columns?.role?.label || 'Role'}</span>,
@@ -7,6 +7,8 @@ import { badge, ownerReference } from './content.config-shared-collections';
7
7
  import { ADR_STATUS_VALUES } from './utils/collections/adr-constants';
8
8
  import fs from 'fs';
9
9
  import path from 'path';
10
+ import { userTeamDirectoryLoader } from './enterprise/directory/user-team-directory';
11
+ import config from '@config';
10
12
 
11
13
  // Enterprise Collections
12
14
  import { customPagesSchema, resourceDocsSchema, resourceDocCategoriesSchema } from './enterprise/collections';
@@ -102,6 +104,11 @@ const resourcePointer = z.object({
102
104
  type: z.enum(['agent', 'service', 'event', 'command', 'query', 'flow', 'channel', 'domain', 'user', 'team', 'container']),
103
105
  });
104
106
 
107
+ const directoryEntrySource = z.object({
108
+ provider: z.string(),
109
+ url: z.string().optional(),
110
+ });
111
+
105
112
  const changelogs = defineCollection({
106
113
  loader: glob({
107
114
  pattern: withIgnoredBuildArtifacts(['**/changelog.(md|mdx)']),
@@ -876,10 +883,15 @@ const entities = defineCollection({
876
883
  });
877
884
 
878
885
  const users = defineCollection({
879
- loader: glob({
880
- pattern: withIgnoredBuildArtifacts('users/*.(md|mdx)'),
881
- base: projectDirBase,
882
- generateId: ({ data }) => data.id as string,
886
+ loader: userTeamDirectoryLoader({
887
+ collection: 'users',
888
+ sources: config.directory?.sources,
889
+ conflictStrategy: config.directory?.conflictStrategy,
890
+ local: {
891
+ pattern: withIgnoredBuildArtifacts('users/*.(md|mdx)'),
892
+ base: projectDirBase,
893
+ generateId: ({ data }) => data.id as string,
894
+ },
883
895
  }),
884
896
  schema: z.object({
885
897
  id: z.string(),
@@ -887,6 +899,8 @@ const users = defineCollection({
887
899
  avatarUrl: z.string(),
888
900
  role: z.string().optional(),
889
901
  hidden: z.boolean().optional(),
902
+ source: directoryEntrySource.optional(),
903
+ readOnly: z.boolean().optional(),
890
904
  email: z.string().optional(),
891
905
  slackDirectMessageUrl: z.string().optional(),
892
906
  msTeamsDirectMessageUrl: z.string().optional(),
@@ -901,10 +915,15 @@ const users = defineCollection({
901
915
  });
902
916
 
903
917
  const teams = defineCollection({
904
- loader: glob({
905
- pattern: withIgnoredBuildArtifacts('teams/*.(md|mdx)'),
906
- base: projectDirBase,
907
- generateId: ({ data }) => data.id as string,
918
+ loader: userTeamDirectoryLoader({
919
+ collection: 'teams',
920
+ sources: config.directory?.sources,
921
+ conflictStrategy: config.directory?.conflictStrategy,
922
+ local: {
923
+ pattern: withIgnoredBuildArtifacts('teams/*.(md|mdx)'),
924
+ base: projectDirBase,
925
+ generateId: ({ data }) => data.id as string,
926
+ },
908
927
  }),
909
928
  schema: z.object({
910
929
  id: z.string(),
@@ -912,6 +931,8 @@ const teams = defineCollection({
912
931
  summary: z.string().optional(),
913
932
  email: z.string().optional(),
914
933
  hidden: z.boolean().optional(),
934
+ source: directoryEntrySource.optional(),
935
+ readOnly: z.boolean().optional(),
915
936
  slackDirectMessageUrl: z.string().optional(),
916
937
  msTeamsDirectMessageUrl: z.string().optional(),
917
938
  members: z.array(reference('users')).optional(),