@apimatic/cli 2.0.0-beta.4 → 2.0.0-beta.6
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/README.md +20 -64
- package/apimatic.schema.json +2 -2
- package/lib/actions/action-result.d.ts +4 -2
- package/lib/actions/action-result.js +8 -3
- package/lib/actions/action-result.js.map +1 -1
- package/lib/actions/api/transform.d.ts +7 -6
- package/lib/actions/api/transform.js +12 -13
- package/lib/actions/api/transform.js.map +1 -1
- package/lib/actions/api/validate.d.ts +4 -5
- package/lib/actions/api/validate.js +30 -32
- package/lib/actions/api/validate.js.map +1 -1
- package/lib/actions/portal/generate.js +3 -3
- package/lib/actions/portal/generate.js.map +1 -1
- package/lib/actions/portal/prepare-project.js +3 -0
- package/lib/actions/portal/prepare-project.js.map +1 -1
- package/lib/actions/quickstart.d.ts +1 -9
- package/lib/actions/quickstart.js +122 -102
- package/lib/actions/quickstart.js.map +1 -1
- package/lib/commands/api/transform.d.ts +1 -1
- package/lib/commands/api/transform.js +2 -2
- package/lib/commands/api/transform.js.map +1 -1
- package/lib/commands/api/validate.d.ts +3 -3
- package/lib/commands/api/validate.js +28 -17
- package/lib/commands/api/validate.js.map +1 -1
- package/lib/commands/plugin/generate.d.ts +1 -1
- package/lib/commands/portal/generate.d.ts +2 -2
- package/lib/commands/portal/generate.js +3 -1
- package/lib/commands/portal/generate.js.map +1 -1
- package/lib/commands/portal/serve.d.ts +2 -2
- package/lib/commands/portal/serve.js +1 -1
- package/lib/commands/sdk/generate.d.ts +1 -1
- package/lib/infrastructure/file-service.d.ts +5 -0
- package/lib/infrastructure/file-service.js +40 -9
- package/lib/infrastructure/file-service.js.map +1 -1
- package/lib/infrastructure/portal-dev-server-service.js +2 -1
- package/lib/infrastructure/portal-dev-server-service.js.map +1 -1
- package/lib/infrastructure/portal-project-service.d.ts +2 -0
- package/lib/infrastructure/portal-project-service.js +9 -4
- package/lib/infrastructure/portal-project-service.js.map +1 -1
- package/lib/infrastructure/services/file-download-service.d.ts +4 -4
- package/lib/infrastructure/services/file-download-service.js +14 -14
- package/lib/infrastructure/services/file-download-service.js.map +1 -1
- package/lib/prompts/api/transform.d.ts +0 -2
- package/lib/prompts/api/transform.js +0 -3
- package/lib/prompts/api/transform.js.map +1 -1
- package/lib/prompts/api/validate.d.ts +2 -2
- package/lib/prompts/api/validate.js +35 -3
- package/lib/prompts/api/validate.js.map +1 -1
- package/lib/prompts/format.d.ts +1 -1
- package/lib/prompts/format.js.map +1 -1
- package/lib/prompts/portal/generate.d.ts +2 -1
- package/lib/prompts/portal/generate.js +22 -6
- package/lib/prompts/portal/generate.js.map +1 -1
- package/lib/prompts/portal/prepare-project.d.ts +5 -1
- package/lib/prompts/portal/prepare-project.js +15 -1
- package/lib/prompts/portal/prepare-project.js.map +1 -1
- package/lib/prompts/portal/serve.js +6 -3
- package/lib/prompts/portal/serve.js.map +1 -1
- package/lib/prompts/portal/source.d.ts +6 -6
- package/lib/prompts/portal/source.js +97 -31
- package/lib/prompts/portal/source.js.map +1 -1
- package/lib/prompts/quickstart.d.ts +14 -13
- package/lib/prompts/quickstart.js +43 -27
- package/lib/prompts/quickstart.js.map +1 -1
- package/lib/types/apimatic-config/document.d.ts +2 -0
- package/lib/types/apimatic-config/document.js +4 -0
- package/lib/types/apimatic-config/document.js.map +1 -1
- package/lib/types/file/directory.js +2 -1
- package/lib/types/file/directory.js.map +1 -1
- package/lib/types/file/directoryPath.d.ts +3 -0
- package/lib/types/file/directoryPath.js +10 -1
- package/lib/types/file/directoryPath.js.map +1 -1
- package/lib/types/file/fileName.d.ts +5 -0
- package/lib/types/file/fileName.js +13 -3
- package/lib/types/file/fileName.js.map +1 -1
- package/lib/types/file/filePath.js +1 -1
- package/lib/types/file/filePath.js.map +1 -1
- package/lib/types/file/resource-input.d.ts +7 -5
- package/lib/types/file/resource-input.js +16 -15
- package/lib/types/file/resource-input.js.map +1 -1
- package/lib/types/flags-provider.d.ts +6 -1
- package/lib/types/flags-provider.js +22 -12
- package/lib/types/flags-provider.js.map +1 -1
- package/lib/types/plugin-config-context.d.ts +3 -0
- package/lib/types/plugin-config-context.js +33 -12
- package/lib/types/plugin-config-context.js.map +1 -1
- package/lib/types/portal/code-samples.d.ts +2 -0
- package/lib/types/portal/code-samples.js +7 -0
- package/lib/types/portal/code-samples.js.map +1 -1
- package/lib/types/portal/config/site-address.d.ts +16 -0
- package/lib/types/portal/config/site-address.js +67 -0
- package/lib/types/portal/config/site-address.js.map +1 -0
- package/lib/types/portal/config/site-config.d.ts +3 -5
- package/lib/types/portal/config/site-config.js +10 -33
- package/lib/types/portal/config/site-config.js.map +1 -1
- package/lib/types/portal/config/static-asset.d.ts +2 -2
- package/lib/types/portal/config/static-asset.js +2 -2
- package/lib/types/portal/config/static-asset.js.map +1 -1
- package/lib/types/portal/content-tree.d.ts +11 -4
- package/lib/types/portal/content-tree.js +31 -20
- package/lib/types/portal/content-tree.js.map +1 -1
- package/lib/types/portal/endpoint.d.ts +1 -0
- package/lib/types/portal/endpoint.js +3 -0
- package/lib/types/portal/endpoint.js.map +1 -1
- package/lib/types/portal/openapi-document.d.ts +4 -0
- package/lib/types/portal/openapi-document.js +12 -0
- package/lib/types/portal/openapi-document.js.map +1 -1
- package/lib/types/portal/page.js +16 -1
- package/lib/types/portal/page.js.map +1 -1
- package/lib/types/portal/portal-config.d.ts +6 -3
- package/lib/types/portal/portal-config.js +8 -4
- package/lib/types/portal/portal-config.js.map +1 -1
- package/lib/types/portal/portal-languages.d.ts +2 -0
- package/lib/types/portal/portal-languages.js +5 -1
- package/lib/types/portal/portal-languages.js.map +1 -1
- package/lib/types/portal/portal-source.d.ts +43 -11
- package/lib/types/portal/shared.d.ts +11 -0
- package/lib/types/portal/shared.js +10 -0
- package/lib/types/portal/shared.js.map +1 -0
- package/lib/types/portal/spec-metadata.d.ts +17 -0
- package/lib/types/portal/spec-metadata.js +40 -0
- package/lib/types/portal/spec-metadata.js.map +1 -0
- package/lib/types/portal-source-context.d.ts +21 -8
- package/lib/types/portal-source-context.js +208 -50
- package/lib/types/portal-source-context.js.map +1 -1
- package/lib/types/project-context.d.ts +18 -0
- package/lib/types/project-context.js +18 -1
- package/lib/types/project-context.js.map +1 -1
- package/lib/types/project-layout.d.ts +3 -0
- package/lib/types/project-layout.js +4 -0
- package/lib/types/project-layout.js.map +1 -1
- package/lib/types/resource-context.d.ts +25 -10
- package/lib/types/resource-context.js +40 -23
- package/lib/types/resource-context.js.map +1 -1
- package/oclif.manifest.json +88 -70
- package/package.json +1 -1
- package/portal-template/dependency-directories.ts +31 -40
- package/portal-template/downloads.ts +6 -3
- package/portal-template/portal-config.ts +4 -0
- package/portal-template/prerender-pages.ts +8 -2
- package/portal-template/spec-reload.ts +12 -9
- package/portal-template/src/components/api-markdown.tsx +32 -0
- package/portal-template/src/components/api-page.tsx +8 -1
- package/portal-template/src/components/authorization-failure.tsx +63 -0
- package/portal-template/src/components/markdown-copy-button.tsx +2 -2
- package/portal-template/src/components/plugin-install.tsx +6 -5
- package/portal-template/src/components/sdk-actions.tsx +3 -2
- package/portal-template/src/components/sdk-cards.tsx +2 -1
- package/portal-template/src/components/search.tsx +9 -2
- package/portal-template/src/lib/base-path.ts +14 -0
- package/portal-template/src/lib/code-titles.ts +8 -0
- package/portal-template/src/lib/copy-markdown.ts +4 -2
- package/portal-template/src/lib/install-command.ts +5 -5
- package/portal-template/src/lib/layout.shared.tsx +5 -3
- package/portal-template/src/lib/llms.server.ts +29 -5
- package/portal-template/src/lib/oauth-callback.ts +63 -0
- package/portal-template/src/lib/portal-types.ts +3 -3
- package/portal-template/src/lib/rehype-code-titles.ts +3 -5
- package/portal-template/src/lib/remark-image-references.ts +35 -0
- package/portal-template/src/lib/search-content.ts +28 -0
- package/portal-template/src/lib/search-options.ts +7 -0
- package/portal-template/src/lib/source.server.ts +2 -0
- package/portal-template/src/router.tsx +3 -1
- package/portal-template/src/routes/$.tsx +3 -2
- package/portal-template/src/routes/__root.tsx +8 -1
- package/portal-template/src/routes/api/search[.]json.ts +23 -2
- package/portal-template/src/routes/oauth.callback.tsx +54 -0
- package/portal-template/static-functions-base.ts +41 -0
- package/portal-template/vite.config.ts +15 -8
|
@@ -3,6 +3,7 @@ import { createServerFn } from '@tanstack/react-start';
|
|
|
3
3
|
import { docs, generated } from '@/lib/source';
|
|
4
4
|
import { source } from '@/lib/source.server';
|
|
5
5
|
import { PortalLayout } from '@/lib/layout';
|
|
6
|
+
import { fullAddress } from '@/lib/base-path';
|
|
6
7
|
import { getPageMarkdownUrl, slugsFromSplat } from '@/lib/shared';
|
|
7
8
|
import { portal } from '@/lib/portal';
|
|
8
9
|
import { absoluteUrl, canonicalLink } from '@/lib/seo';
|
|
@@ -129,7 +130,7 @@ function Content({
|
|
|
129
130
|
const PageBody = page.body;
|
|
130
131
|
const pathname = usePathname();
|
|
131
132
|
// Named, or the popover reads `window.location.href` and sends the reader's query and hash on.
|
|
132
|
-
const pageUrl =
|
|
133
|
+
const pageUrl = fullAddress(pathname);
|
|
133
134
|
|
|
134
135
|
return (
|
|
135
136
|
<DocsPage toc={toc} full={page.full}>
|
|
@@ -137,7 +138,7 @@ function Content({
|
|
|
137
138
|
<DocsDescription>{page.description}</DocsDescription>
|
|
138
139
|
<div className="flex flex-row gap-2 items-center border-b -mt-4 pb-6">
|
|
139
140
|
{/* Keyed so a new page starts at "Copy Markdown", not at the last page's result. */}
|
|
140
|
-
<MarkdownCopyButton key={markdownUrl} markdownUrl={markdownUrl}
|
|
141
|
+
<MarkdownCopyButton key={markdownUrl} markdownUrl={markdownUrl} />
|
|
141
142
|
{/* Sends the reader to an external AI vendor, so a portal published under someone
|
|
142
143
|
else's brand can turn it off. */}
|
|
143
144
|
{portal.pageActions ? <ViewOptionsPopover markdownUrl={markdownUrl} pageUrl={pageUrl} /> : null}
|
|
@@ -5,6 +5,7 @@ import { source } from '@/lib/source.server';
|
|
|
5
5
|
import appCss from '@/styles/app.css?url';
|
|
6
6
|
import { RootProvider } from 'fumadocs-ui/provider/tanstack';
|
|
7
7
|
import SearchDialog from '@/components/search';
|
|
8
|
+
import { withBasePath } from '@/lib/base-path';
|
|
8
9
|
import { portal } from '@/lib/portal';
|
|
9
10
|
|
|
10
11
|
// The sidebar tree is the same on every page. Loaded here, once, it is written to a single
|
|
@@ -15,7 +16,13 @@ const loadPageTree = createServerFn({ method: 'GET' })
|
|
|
15
16
|
|
|
16
17
|
// Without one the browser tab shows the blank-document icon on every page.
|
|
17
18
|
const iconLinks = portal.favicon
|
|
18
|
-
? [
|
|
19
|
+
? [
|
|
20
|
+
{
|
|
21
|
+
rel: 'icon',
|
|
22
|
+
href: withBasePath(portal.favicon.url),
|
|
23
|
+
...(portal.favicon.type ? { type: portal.favicon.type } : {})
|
|
24
|
+
}
|
|
25
|
+
]
|
|
19
26
|
: [];
|
|
20
27
|
|
|
21
28
|
// A portal fixed to one mode keeps to it whatever the visitor's system prefers, and offers no
|
|
@@ -1,9 +1,30 @@
|
|
|
1
1
|
import { createFileRoute } from '@tanstack/react-router';
|
|
2
|
-
import {
|
|
2
|
+
import { withoutImages } from '@/lib/search-content';
|
|
3
|
+
import { type PortalPage, source } from '@/lib/source.server';
|
|
3
4
|
import { createFromSource } from 'fumadocs-core/search/server';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
// Fumadocs indexes a reference page's description as written, so results show its images, without the path.
|
|
7
|
+
const server = createFromSource(
|
|
8
|
+
{ ...source, getPages: (language?: string) => source.getPages(language).map(searchable) },
|
|
9
|
+
{ language: 'english' }
|
|
10
|
+
);
|
|
6
11
|
|
|
7
12
|
export const Route = createFileRoute('/api/search.json')({
|
|
8
13
|
server: { handlers: { GET: () => server.staticGET() } }
|
|
9
14
|
});
|
|
15
|
+
|
|
16
|
+
/** A reference page as Fumadocs indexes a page of its own: without images. */
|
|
17
|
+
function searchable(page: PortalPage): PortalPage {
|
|
18
|
+
if (page.type !== 'openapi') return page;
|
|
19
|
+
const { description, structuredData } = page.data;
|
|
20
|
+
const contents = structuredData.contents.map((item) => ({ ...item, content: withoutImages(item.content) }));
|
|
21
|
+
// Both alike, or Fumadocs no longer finds the description among the contents and indexes it a second time.
|
|
22
|
+
return {
|
|
23
|
+
...page,
|
|
24
|
+
data: {
|
|
25
|
+
...page.data,
|
|
26
|
+
description: description && withoutImages(description),
|
|
27
|
+
structuredData: { ...structuredData, contents }
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
2
|
+
import { HomeLayout } from 'fumadocs-ui/layouts/home';
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
import { AuthorizationFailure } from '@/components/authorization-failure';
|
|
5
|
+
import { baseOptions } from '@/lib/layout.shared';
|
|
6
|
+
import { forgetStartingPage, oauthCallback, type OAuthCallback, type OAuthCallbackFailure } from '@/lib/oauth-callback';
|
|
7
|
+
import { portal } from '@/lib/portal';
|
|
8
|
+
|
|
9
|
+
// Published portals are static, so this page does in the browser what Fumadocs'
|
|
10
|
+
// `createOAuthHandler()` route does on a server.
|
|
11
|
+
export const Route = createFileRoute('/oauth/callback')({
|
|
12
|
+
head: () => ({ meta: [{ title: `Authorization | ${portal.name}` }, { name: 'robots', content: 'noindex' }] }),
|
|
13
|
+
component: OAuthCallbackPage
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
let completion: OAuthCallback | undefined;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Reading the cookie and sending the browser on can each happen only once per page load, not
|
|
20
|
+
* once per mount: the StrictMode `portal serve` runs under mounts the page twice, and the second
|
|
21
|
+
* mount would find the cookie gone. The answer is kept, so a later mount in the same load, such
|
|
22
|
+
* as Back after leaving through the header, shows the same outcome. Every arrival from a provider
|
|
23
|
+
* is a new load.
|
|
24
|
+
*/
|
|
25
|
+
function completeAuthorization(): OAuthCallback {
|
|
26
|
+
if (completion === undefined) {
|
|
27
|
+
completion = oauthCallback(document.cookie, window.location);
|
|
28
|
+
forgetStartingPage();
|
|
29
|
+
if (completion.kind === 'return') window.location.replace(completion.url);
|
|
30
|
+
}
|
|
31
|
+
return completion;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function OAuthCallbackPage() {
|
|
35
|
+
// Null until the effect has read the cookie, which the prerendered page cannot.
|
|
36
|
+
const [failure, setFailure] = useState<OAuthCallbackFailure | null>(null);
|
|
37
|
+
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
const callback = completeAuthorization();
|
|
40
|
+
if (callback.kind !== 'return') setFailure(callback);
|
|
41
|
+
}, []);
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<HomeLayout {...baseOptions()}>
|
|
45
|
+
<div className="flex flex-col px-8 justify-center flex-1 text-center items-center gap-4">
|
|
46
|
+
{failure === null ? (
|
|
47
|
+
<p className="text-fd-muted-foreground">Completing authorization…</p>
|
|
48
|
+
) : (
|
|
49
|
+
<AuthorizationFailure failure={failure} />
|
|
50
|
+
)}
|
|
51
|
+
</div>
|
|
52
|
+
</HomeLayout>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
import { withBasePath } from './src/lib/base-path';
|
|
3
|
+
|
|
4
|
+
/** The package whose browser half fetches a prerendered server function's result. */
|
|
5
|
+
const PACKAGE = /[\\/]@tanstack[\\/]start-static-server-functions[\\/]/;
|
|
6
|
+
|
|
7
|
+
/** Where it fetches that result from, opening backtick included so nothing else naming the folder matches. */
|
|
8
|
+
export const CACHE_ADDRESS = '`/__tsr/staticServerFnCache/';
|
|
9
|
+
|
|
10
|
+
/** Puts the browser's fetch of prerendered page data under the base, until TanStack/router#6152 does it itself. */
|
|
11
|
+
export function staticFunctionsBase(): Plugin {
|
|
12
|
+
let base = '/';
|
|
13
|
+
let found = false;
|
|
14
|
+
return {
|
|
15
|
+
name: 'apimatic:static-functions-base',
|
|
16
|
+
apply: 'build',
|
|
17
|
+
enforce: 'pre',
|
|
18
|
+
// The server writes the files under the output directory, which the host already serves at the base.
|
|
19
|
+
applyToEnvironment: (environment) => environment.name === 'client',
|
|
20
|
+
configResolved(config) {
|
|
21
|
+
base = config.base;
|
|
22
|
+
},
|
|
23
|
+
transform: {
|
|
24
|
+
filter: { id: PACKAGE, code: CACHE_ADDRESS },
|
|
25
|
+
handler(code) {
|
|
26
|
+
// Found at the root too, where the replacement is the address itself.
|
|
27
|
+
found = true;
|
|
28
|
+
return code.replaceAll(CACHE_ADDRESS, '`' + withBasePath(CACHE_ADDRESS.slice(1), base));
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
// An upgrade that moves the address fails the build, rather than every link in the portal.
|
|
32
|
+
buildEnd(error) {
|
|
33
|
+
if (error === undefined && !found) {
|
|
34
|
+
this.error(
|
|
35
|
+
`No module of @tanstack/start-static-server-functions holds ${CACHE_ADDRESS}, so a portal ` +
|
|
36
|
+
'served under a path could not load the pages its links lead to. See portal-template/static-functions-base.ts.'
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { fileURLToPath } from 'node:url';
|
|
2
2
|
import react from '@vitejs/plugin-react';
|
|
3
3
|
import { tanstackStart } from '@tanstack/react-start/plugin/vite';
|
|
4
|
-
import { defineConfig } from 'vite';
|
|
4
|
+
import { defineConfig, searchForWorkspaceRoot } from 'vite';
|
|
5
5
|
import tailwindcss from '@tailwindcss/vite';
|
|
6
6
|
import { fumadocsMdx } from 'fumadocs-mdx/vite';
|
|
7
7
|
import { dependencyDirectories } from './dependency-directories.ts';
|
|
@@ -10,25 +10,34 @@ import { generatedPagesReload } from './generated-pages-reload.ts';
|
|
|
10
10
|
import { readBuildPaths, readPortalIdentity } from './portal-config.ts';
|
|
11
11
|
import { prerenderPages } from './prerender-pages.ts';
|
|
12
12
|
import { specReload } from './spec-reload.ts';
|
|
13
|
+
import { remarkImageReferences } from './src/lib/remark-image-references.ts';
|
|
14
|
+
import { staticFunctionsBase } from './static-functions-base.ts';
|
|
13
15
|
|
|
14
16
|
export default defineConfig(async () => {
|
|
15
17
|
const [paths, identity] = await Promise.all([readBuildPaths(), readPortalIdentity()]);
|
|
16
18
|
const pages = await prerenderPages(paths, identity.siteUrl);
|
|
17
19
|
const publicDir: string | false = paths.staticDir ?? false;
|
|
18
|
-
const
|
|
20
|
+
const portalProjectDirectory = fileURLToPath(new URL('.', import.meta.url));
|
|
19
21
|
|
|
20
22
|
return {
|
|
23
|
+
// TanStack Start derives the router's basepath and every asset URL from it.
|
|
24
|
+
base: paths.base,
|
|
21
25
|
publicDir,
|
|
22
26
|
plugins: [
|
|
23
27
|
generatedPagesReload(),
|
|
24
28
|
downloads(paths.downloadsDir),
|
|
29
|
+
staticFunctionsBase(),
|
|
25
30
|
// `/images/logo.png` is read from the static directory, and a remote image is never fetched for its size.
|
|
26
31
|
fumadocsMdx({
|
|
27
32
|
globalOptions: {
|
|
28
|
-
mdxOptions: {
|
|
33
|
+
mdxOptions: {
|
|
34
|
+
remarkImageOptions: { publicDir: publicDir || undefined, external: false },
|
|
35
|
+
// A function, so it runs ahead of the preset's own plugins, `remarkImage` among them.
|
|
36
|
+
remarkPlugins: (plugins) => [remarkImageReferences, ...plugins]
|
|
37
|
+
}
|
|
29
38
|
}
|
|
30
39
|
}),
|
|
31
|
-
specReload(paths.
|
|
40
|
+
specReload(paths.specDir),
|
|
32
41
|
tailwindcss(),
|
|
33
42
|
tanstackStart({
|
|
34
43
|
// Without a mask path the shell is rendered at "/" and no index.html is written;
|
|
@@ -57,13 +66,11 @@ export default defineConfig(async () => {
|
|
|
57
66
|
// listens on `::1` alone, a connect that stalls under load falls back to 127.0.0.1 and is
|
|
58
67
|
// refused, failing the build; binding IPv4 leaves the fetch a single address to reach.
|
|
59
68
|
preview: { host: '127.0.0.1' },
|
|
60
|
-
// Spelled out because the default, the project alone, misses the CLI installation the
|
|
61
|
-
// dependencies are linked from, and the static directory pages import images from.
|
|
62
69
|
server: {
|
|
63
70
|
fs: {
|
|
64
71
|
allow: [
|
|
65
|
-
|
|
66
|
-
...dependencyDirectories(
|
|
72
|
+
searchForWorkspaceRoot(portalProjectDirectory),
|
|
73
|
+
...dependencyDirectories(portalProjectDirectory),
|
|
67
74
|
...(paths.staticDir === null ? [] : [paths.staticDir])
|
|
68
75
|
]
|
|
69
76
|
}
|