@jk2908/solas 0.2.3 → 0.3.1
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/CHANGELOG.md +20 -0
- package/README.md +2 -0
- package/dist/cli.js +77 -83
- package/dist/error-boundary.d.ts +1 -1
- package/dist/error-boundary.js +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +10 -14
- package/dist/internal/build.d.ts +1 -1
- package/dist/internal/build.js +4 -4
- package/dist/internal/codegen/config.d.ts +1 -1
- package/dist/internal/codegen/config.js +20 -11
- package/dist/internal/codegen/environments.js +25 -21
- package/dist/internal/codegen/manifest.d.ts +1 -1
- package/dist/internal/codegen/manifest.js +7 -8
- package/dist/internal/codegen/maps.d.ts +1 -1
- package/dist/internal/codegen/maps.js +35 -28
- package/dist/internal/codegen/utils.d.ts +30 -0
- package/dist/internal/codegen/utils.js +165 -1
- package/dist/internal/env/browser.js +20 -16
- package/dist/internal/env/request-context.d.ts +2 -2
- package/dist/internal/env/request-context.js +1 -1
- package/dist/internal/env/rsc.d.ts +8 -22
- package/dist/internal/env/rsc.js +38 -117
- package/dist/internal/env/ssr.js +9 -9
- package/dist/internal/env/utils.js +2 -2
- package/dist/internal/metadata.d.ts +2 -2
- package/dist/internal/metadata.js +18 -6
- package/dist/internal/navigation/http-exception-boundary.d.ts +2 -2
- package/dist/internal/navigation/http-exception-boundary.js +1 -1
- package/dist/internal/navigation/link.js +1 -1
- package/dist/internal/navigation/redirect-boundary.d.ts +1 -1
- package/dist/internal/navigation/redirect-boundary.js +1 -1
- package/dist/internal/navigation/redirect.js +1 -1
- package/dist/internal/navigation/use-search-params.d.ts +11 -1
- package/dist/internal/navigation/use-search-params.js +24 -3
- package/dist/internal/prerender.d.ts +10 -1
- package/dist/internal/prerender.js +55 -5
- package/dist/internal/render/head.d.ts +4 -1
- package/dist/internal/render/head.js +37 -18
- package/dist/internal/render/tree.d.ts +1 -1
- package/dist/internal/render/tree.js +3 -3
- package/dist/internal/router/create-router.d.ts +2 -2
- package/dist/internal/router/create-router.js +1 -1
- package/dist/internal/router/prefetcher.d.ts +1 -1
- package/dist/internal/router/prefetcher.js +8 -3
- package/dist/internal/router/resolver.d.ts +29 -29
- package/dist/internal/router/resolver.js +4 -4
- package/dist/internal/router/router-context.d.ts +4 -0
- package/dist/internal/router/router-context.js +1 -0
- package/dist/internal/router/router-provider.d.ts +6 -2
- package/dist/internal/router/router-provider.js +38 -22
- package/dist/internal/router/router.d.ts +1 -1
- package/dist/internal/router/router.js +4 -4
- package/dist/internal/router/use-router.d.ts +5 -1
- package/dist/internal/router/use-router.js +1 -1
- package/dist/internal/router/utils.d.ts +1 -1
- package/dist/internal/server/actions.d.ts +30 -0
- package/dist/internal/server/actions.js +107 -0
- package/dist/internal/server/cookies.d.ts +1 -1
- package/dist/internal/server/cookies.js +3 -3
- package/dist/internal/server/dynamic.js +2 -2
- package/dist/internal/server/headers.js +2 -2
- package/dist/internal/server/url.js +14 -3
- package/dist/internal/ui/defaults/error.d.ts +1 -1
- package/dist/internal/ui/error-boundary.d.ts +1 -1
- package/dist/internal/ui/error-boundary.js +1 -1
- package/dist/navigation.d.ts +6 -6
- package/dist/navigation.js +6 -6
- package/dist/prerender.d.ts +1 -1
- package/dist/prerender.js +1 -1
- package/dist/router.d.ts +4 -4
- package/dist/router.js +4 -4
- package/dist/server.d.ts +4 -4
- package/dist/server.js +4 -4
- package/dist/solas.d.ts +1 -1
- package/dist/solas.js +1 -0
- package/dist/types.d.ts +6 -6
- package/dist/types.js +1 -1
- package/dist/utils/context.js +1 -1
- package/dist/utils/logger.js +2 -2
- package/package.json +3 -1
- package/dist/utils/format.d.ts +0 -6
- package/dist/utils/format.js +0 -72
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
export declare function useRouter(): {
|
|
2
|
-
go: (to: string, opts?: import("./router-context").Navigation.GoOptions | undefined) => Promise<string>;
|
|
2
|
+
go: (to: string, opts?: import("./router-context.js").Navigation.GoOptions | undefined) => Promise<string>;
|
|
3
3
|
prefetch: (path: string) => void;
|
|
4
4
|
isNavigating: boolean;
|
|
5
|
+
url: {
|
|
6
|
+
pathname?: string | undefined;
|
|
7
|
+
search?: string | undefined;
|
|
8
|
+
};
|
|
5
9
|
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ReactFormState } from 'react-dom/client';
|
|
2
|
+
import { SolasRequest } from '../../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Check if a request is an action request and reuse parsed FormData
|
|
5
|
+
* when multipart action detection already had to inspect the body
|
|
6
|
+
*/
|
|
7
|
+
export declare function maybeAction(req: Request): Promise<{
|
|
8
|
+
action: boolean;
|
|
9
|
+
formData: null;
|
|
10
|
+
} | {
|
|
11
|
+
action: boolean;
|
|
12
|
+
formData: FormData;
|
|
13
|
+
}>;
|
|
14
|
+
/**
|
|
15
|
+
* Process an incoming action request, either from ReactClient.setServerCallback or a <form action={...}> submission
|
|
16
|
+
* @returns an object containing either the return value of the action or the form state, depending on the type
|
|
17
|
+
* of action request
|
|
18
|
+
*/
|
|
19
|
+
export declare function processActionRequest(req: SolasRequest): Promise<{
|
|
20
|
+
returnValue: {
|
|
21
|
+
ok: boolean;
|
|
22
|
+
data: unknown;
|
|
23
|
+
} | undefined;
|
|
24
|
+
formState: ReactFormState | undefined;
|
|
25
|
+
temporaryReferences: unknown;
|
|
26
|
+
}>;
|
|
27
|
+
/**
|
|
28
|
+
* Check whether an action request came from the same origin as the target app
|
|
29
|
+
*/
|
|
30
|
+
export declare function isTrustedActionRequest(req: Request): boolean;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { createTemporaryReferenceSet, decodeAction, decodeFormState, decodeReply, loadServerAction, } from '@vitejs/plugin-rsc/rsc';
|
|
2
|
+
import { Solas } from '../../solas.js';
|
|
3
|
+
import { HttpException } from '../navigation/http-exception.js';
|
|
4
|
+
/**
|
|
5
|
+
* Check if a request is an action request and reuse parsed FormData
|
|
6
|
+
* when multipart action detection already had to inspect the body
|
|
7
|
+
*/
|
|
8
|
+
export async function maybeAction(req) {
|
|
9
|
+
if (req.method !== 'POST')
|
|
10
|
+
return { action: false, formData: null };
|
|
11
|
+
if (req.headers.has('x-rsc-action-id'))
|
|
12
|
+
return { action: true, formData: null };
|
|
13
|
+
const contentType = req.headers.get('content-type') ?? '';
|
|
14
|
+
if (!contentType.startsWith('multipart/form-data')) {
|
|
15
|
+
return { action: false, formData: null };
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
const formData = await req.clone().formData();
|
|
19
|
+
for (const key of formData.keys()) {
|
|
20
|
+
if (key === '$ACTION_KEY' ||
|
|
21
|
+
key.startsWith('$ACTION_') ||
|
|
22
|
+
key.startsWith('$ACTION_REF_')) {
|
|
23
|
+
return { action: true, formData };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return { action: false, formData: null };
|
|
29
|
+
}
|
|
30
|
+
return { action: false, formData: null };
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Process an incoming action request, either from ReactClient.setServerCallback or a <form action={...}> submission
|
|
34
|
+
* @returns an object containing either the return value of the action or the form state, depending on the type
|
|
35
|
+
* of action request
|
|
36
|
+
*/
|
|
37
|
+
export async function processActionRequest(req) {
|
|
38
|
+
let returnValue;
|
|
39
|
+
let formState;
|
|
40
|
+
let temporaryReferences;
|
|
41
|
+
// reject cross-site action posts before any body decoding or action loading
|
|
42
|
+
if (!isTrustedActionRequest(req)) {
|
|
43
|
+
throw new HttpException(403, 'Cross-site action requests are forbidden');
|
|
44
|
+
}
|
|
45
|
+
const id = req.headers.get('x-rsc-action-id');
|
|
46
|
+
if (id) {
|
|
47
|
+
// x-rsc-action-id header exists when action is
|
|
48
|
+
// called via ReactClient.setServerCallback
|
|
49
|
+
const body = req.headers.get('content-type')?.startsWith('multipart/form-data')
|
|
50
|
+
? await req.formData()
|
|
51
|
+
: await req.text();
|
|
52
|
+
temporaryReferences = createTemporaryReferenceSet();
|
|
53
|
+
const args = await decodeReply(body, {
|
|
54
|
+
temporaryReferences,
|
|
55
|
+
});
|
|
56
|
+
const action = await loadServerAction(id);
|
|
57
|
+
try {
|
|
58
|
+
const data = await action.apply(null, args);
|
|
59
|
+
returnValue = { ok: true, data };
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
returnValue = { ok: false, data: err };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
// otherwise server function is called via
|
|
67
|
+
// <form action={...}>
|
|
68
|
+
// we might have already parsed FormData in the router for multipart action
|
|
69
|
+
// detection should be attached to the SolasRequest, so we can reuse that
|
|
70
|
+
// to avoid parsing twice
|
|
71
|
+
const parsedFormData = req[Solas.Config.REQUEST_META]?.parsedFormData;
|
|
72
|
+
const formData = parsedFormData ?? (await req.formData());
|
|
73
|
+
const decodedAction = await decodeAction(formData);
|
|
74
|
+
const result = await decodedAction();
|
|
75
|
+
formState = await decodeFormState(result, formData);
|
|
76
|
+
}
|
|
77
|
+
return { returnValue, formState, temporaryReferences };
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Reduce Origin and Referer headers to a comparable origin string
|
|
81
|
+
*/
|
|
82
|
+
function toOrigin(value) {
|
|
83
|
+
if (!value)
|
|
84
|
+
return null;
|
|
85
|
+
try {
|
|
86
|
+
return new URL(value).origin;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Check whether an action request came from the same origin as the target app
|
|
94
|
+
*/
|
|
95
|
+
export function isTrustedActionRequest(req) {
|
|
96
|
+
const requestOrigin = toOrigin(req.url);
|
|
97
|
+
if (!requestOrigin)
|
|
98
|
+
return false;
|
|
99
|
+
const origin = toOrigin(req.headers.get('origin'));
|
|
100
|
+
if (origin)
|
|
101
|
+
return origin === requestOrigin;
|
|
102
|
+
// some user agents omit Origin on same-origin form posts, so fall back to Referer
|
|
103
|
+
const referer = toOrigin(req.headers.get('referer'));
|
|
104
|
+
if (referer)
|
|
105
|
+
return referer === requestOrigin;
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Cookies } from '../../utils/cookies';
|
|
2
|
-
import { RequestContext } from '../env/request-context';
|
|
3
|
-
import { dynamic } from './dynamic';
|
|
1
|
+
import { Cookies } from '../../utils/cookies.js';
|
|
2
|
+
import { RequestContext } from '../env/request-context.js';
|
|
3
|
+
import { dynamic } from './dynamic.js';
|
|
4
4
|
/**
|
|
5
5
|
* Get the request cookies as a Cookies instance
|
|
6
6
|
* @returns a read-only Cookies instance containing the request cookies
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Logger } from '../../utils/logger';
|
|
2
|
-
import { RequestContext } from '../env/request-context';
|
|
1
|
+
import { Logger } from '../../utils/logger.js';
|
|
2
|
+
import { RequestContext } from '../env/request-context.js';
|
|
3
3
|
const logger = new Logger();
|
|
4
4
|
const NEVER = new Promise(() => { });
|
|
5
5
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RequestContext } from '../env/request-context';
|
|
2
|
-
import { dynamic } from './dynamic';
|
|
1
|
+
import { RequestContext } from '../env/request-context.js';
|
|
2
|
+
import { dynamic } from './dynamic.js';
|
|
3
3
|
/**
|
|
4
4
|
* Get the request headers as a read-only map
|
|
5
5
|
* @returns a read-only map of request headers
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Logger } from '../../utils/logger.js';
|
|
2
|
+
import { RequestContext } from '../env/request-context.js';
|
|
3
|
+
import { dynamic } from './dynamic.js';
|
|
4
|
+
const logger = new Logger();
|
|
3
5
|
/**
|
|
4
6
|
* Get the request url as a URL instance
|
|
5
7
|
* @returns a URL instance containing the request url
|
|
@@ -11,7 +13,16 @@ export function url() {
|
|
|
11
13
|
// without corrupting the cached instance shared across the request
|
|
12
14
|
if (cache.url)
|
|
13
15
|
return new URL(cache.url);
|
|
14
|
-
|
|
16
|
+
let parsed;
|
|
17
|
+
try {
|
|
18
|
+
parsed = new URL(req.url);
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
// if we throw the original error here, the rest of the code gets a messy parsing error
|
|
22
|
+
// instead of a simple 'invalid request url' failure
|
|
23
|
+
logger.error(`[url] invalid request url: ${req.url}`, err);
|
|
24
|
+
throw new Error('Invalid request url', { cause: err });
|
|
25
|
+
}
|
|
15
26
|
cache.url = parsed;
|
|
16
27
|
return new URL(parsed);
|
|
17
28
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Component } from 'react';
|
|
2
|
-
import type { BoundaryError } from '../../types';
|
|
2
|
+
import type { BoundaryError } from '../../types.js';
|
|
3
3
|
export type Props = {
|
|
4
4
|
fallback: ((error: BoundaryError, reset: () => void) => React.ReactNode) | React.ReactNode;
|
|
5
5
|
onError?: (error: BoundaryError) => void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { Component } from 'react';
|
|
3
|
-
import { isKnownError } from '../env/utils';
|
|
3
|
+
import { isKnownError } from '../env/utils.js';
|
|
4
4
|
/**
|
|
5
5
|
* A component that catches synchronous errors in its child component tree and displays a fallback UI
|
|
6
6
|
* @param props - the props for the component
|
package/dist/navigation.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export { Link } from './internal/navigation/link';
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
6
|
-
export { useSearchParams } from './internal/navigation/use-search-params';
|
|
1
|
+
export { HttpExceptionBoundary } from './internal/navigation/http-exception-boundary.js';
|
|
2
|
+
export { HttpException, abort, isHttpException, } from './internal/navigation/http-exception.js';
|
|
3
|
+
export { Link } from './internal/navigation/link.js';
|
|
4
|
+
export { RedirectBoundary } from './internal/navigation/redirect-boundary.js';
|
|
5
|
+
export { Redirect, isRedirect, redirect } from './internal/navigation/redirect.js';
|
|
6
|
+
export { useSearchParams } from './internal/navigation/use-search-params.js';
|
package/dist/navigation.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export { Link } from './internal/navigation/link';
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
6
|
-
export { useSearchParams } from './internal/navigation/use-search-params';
|
|
1
|
+
export { HttpExceptionBoundary } from './internal/navigation/http-exception-boundary.js';
|
|
2
|
+
export { HttpException, abort, isHttpException, } from './internal/navigation/http-exception.js';
|
|
3
|
+
export { Link } from './internal/navigation/link.js';
|
|
4
|
+
export { RedirectBoundary } from './internal/navigation/redirect-boundary.js';
|
|
5
|
+
export { Redirect, isRedirect, redirect } from './internal/navigation/redirect.js';
|
|
6
|
+
export { useSearchParams } from './internal/navigation/use-search-params.js';
|
package/dist/prerender.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { Prerender } from './internal/prerender';
|
|
1
|
+
export { Prerender } from './internal/prerender.js';
|
package/dist/prerender.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { Prerender } from './internal/prerender';
|
|
1
|
+
export { Prerender } from './internal/prerender.js';
|
package/dist/router.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createRouter } from './internal/router/create-router';
|
|
2
|
-
export { Router } from './internal/router/router';
|
|
3
|
-
export { RouterProvider } from './internal/router/router-provider';
|
|
4
|
-
export { useRouter } from './internal/router/use-router';
|
|
1
|
+
export { createRouter } from './internal/router/create-router.js';
|
|
2
|
+
export { Router } from './internal/router/router.js';
|
|
3
|
+
export { RouterProvider } from './internal/router/router-provider.js';
|
|
4
|
+
export { useRouter } from './internal/router/use-router.js';
|
package/dist/router.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { createRouter } from './internal/router/create-router';
|
|
2
|
-
export { Router } from './internal/router/router';
|
|
3
|
-
export { RouterProvider } from './internal/router/router-provider';
|
|
4
|
-
export { useRouter } from './internal/router/use-router';
|
|
1
|
+
export { createRouter } from './internal/router/create-router.js';
|
|
2
|
+
export { Router } from './internal/router/router.js';
|
|
3
|
+
export { RouterProvider } from './internal/router/router-provider.js';
|
|
4
|
+
export { useRouter } from './internal/router/use-router.js';
|
package/dist/server.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { cookies } from './internal/server/cookies';
|
|
2
|
-
export { dynamic } from './internal/server/dynamic';
|
|
3
|
-
export { headers } from './internal/server/headers';
|
|
4
|
-
export { url } from './internal/server/url';
|
|
1
|
+
export { cookies } from './internal/server/cookies.js';
|
|
2
|
+
export { dynamic } from './internal/server/dynamic.js';
|
|
3
|
+
export { headers } from './internal/server/headers.js';
|
|
4
|
+
export { url } from './internal/server/url.js';
|
package/dist/server.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { cookies } from './internal/server/cookies';
|
|
2
|
-
export { dynamic } from './internal/server/dynamic';
|
|
3
|
-
export { headers } from './internal/server/headers';
|
|
4
|
-
export { url } from './internal/server/url';
|
|
1
|
+
export { cookies } from './internal/server/cookies.js';
|
|
2
|
+
export { dynamic } from './internal/server/dynamic.js';
|
|
3
|
+
export { headers } from './internal/server/headers.js';
|
|
4
|
+
export { url } from './internal/server/url.js';
|
package/dist/solas.d.ts
CHANGED
package/dist/solas.js
CHANGED
package/dist/types.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
type BunRequest = Request & {
|
|
2
2
|
params?: Record<string, string | string[]>;
|
|
3
3
|
};
|
|
4
|
-
import { Solas } from './solas';
|
|
5
|
-
import { ExportReader } from './utils/export-reader';
|
|
6
|
-
import type { Build } from './internal/build';
|
|
7
|
-
import type { Metadata } from './internal/metadata';
|
|
8
|
-
import type { HttpException } from './internal/navigation/http-exception';
|
|
9
|
-
import type { Router } from './internal/router/router';
|
|
4
|
+
import { Solas } from './solas.js';
|
|
5
|
+
import { ExportReader } from './utils/export-reader.js';
|
|
6
|
+
import type { Build } from './internal/build.js';
|
|
7
|
+
import type { Metadata } from './internal/metadata.js';
|
|
8
|
+
import type { HttpException } from './internal/navigation/http-exception.js';
|
|
9
|
+
import type { Router } from './internal/router/router.js';
|
|
10
10
|
export type LogLevel = (typeof Solas.Config.LOG_LEVELS)[number];
|
|
11
11
|
type PluginConfigBase = {
|
|
12
12
|
port?: number;
|
package/dist/types.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import { Solas } from './solas';
|
|
1
|
+
import { Solas } from './solas.js';
|
package/dist/utils/context.js
CHANGED
package/dist/utils/logger.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jk2908/solas",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "A React Server Components meta-framework powered by Vite",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"framework",
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
},
|
|
25
25
|
"files": [
|
|
26
26
|
"dist",
|
|
27
|
+
"CHANGELOG.md",
|
|
27
28
|
"README.md",
|
|
28
29
|
"LICENSE"
|
|
29
30
|
],
|
|
@@ -96,6 +97,7 @@
|
|
|
96
97
|
"@types/bun": "^1.2.22",
|
|
97
98
|
"@typescript/native-preview": "^7.0.0-dev.20260224.1",
|
|
98
99
|
"network-information-types": "^0.1.1",
|
|
100
|
+
"oxfmt": "^0.35.0",
|
|
99
101
|
"typescript": "^5.9.3"
|
|
100
102
|
},
|
|
101
103
|
"peerDependencies": {
|
package/dist/utils/format.d.ts
DELETED
package/dist/utils/format.js
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import { format } from 'oxfmt';
|
|
3
|
-
import { Logger } from './logger';
|
|
4
|
-
const logger = new Logger();
|
|
5
|
-
const BASE_OPTIONS = {
|
|
6
|
-
useTabs: true,
|
|
7
|
-
tabWidth: 2,
|
|
8
|
-
printWidth: 90,
|
|
9
|
-
singleQuote: true,
|
|
10
|
-
jsxSingleQuote: false,
|
|
11
|
-
quoteProps: 'as-needed',
|
|
12
|
-
trailingComma: 'all',
|
|
13
|
-
semi: false,
|
|
14
|
-
arrowParens: 'avoid',
|
|
15
|
-
bracketSameLine: true,
|
|
16
|
-
bracketSpacing: true,
|
|
17
|
-
endOfLine: 'lf',
|
|
18
|
-
};
|
|
19
|
-
const SUPPORTED_EXTENSIONS = new Set([
|
|
20
|
-
'.js',
|
|
21
|
-
'.jsx',
|
|
22
|
-
'.ts',
|
|
23
|
-
'.tsx',
|
|
24
|
-
'.mjs',
|
|
25
|
-
'.cjs',
|
|
26
|
-
'.mts',
|
|
27
|
-
'.cts',
|
|
28
|
-
'.json',
|
|
29
|
-
'.jsonc',
|
|
30
|
-
'.json5',
|
|
31
|
-
'.css',
|
|
32
|
-
'.scss',
|
|
33
|
-
'.less',
|
|
34
|
-
'.md',
|
|
35
|
-
'.mdx',
|
|
36
|
-
'.html',
|
|
37
|
-
'.yml',
|
|
38
|
-
'.yaml',
|
|
39
|
-
'.toml',
|
|
40
|
-
]);
|
|
41
|
-
export { Format };
|
|
42
|
-
var Format;
|
|
43
|
-
(function (Format) {
|
|
44
|
-
/**
|
|
45
|
-
* Format a file in-place using oxfmt with our preferred code style
|
|
46
|
-
*/
|
|
47
|
-
async function run(filePath) {
|
|
48
|
-
try {
|
|
49
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
50
|
-
if (!SUPPORTED_EXTENSIONS.has(ext)) {
|
|
51
|
-
logger.warn(`[format] Skipping unsupported file type: ${filePath}`);
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
const file = Bun.file(filePath);
|
|
55
|
-
const source = await file.text();
|
|
56
|
-
const options = ext === '.json' ? { ...BASE_OPTIONS, trailingComma: 'none' } : BASE_OPTIONS;
|
|
57
|
-
const result = await format(filePath, source, options);
|
|
58
|
-
if (result.errors.length > 0) {
|
|
59
|
-
logger.warn(`[format] oxfmt failed for ${filePath}: ${result.errors[0]?.message}`);
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
if (result.code === source)
|
|
63
|
-
return;
|
|
64
|
-
await Bun.write(filePath, result.code);
|
|
65
|
-
logger.info(`[format] Formatted file: ${filePath}`);
|
|
66
|
-
}
|
|
67
|
-
catch (err) {
|
|
68
|
-
logger.error(`[format] Failed to format file: ${filePath}`, err);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
Format.run = run;
|
|
72
|
-
})(Format || (Format = {}));
|