This commit is contained in:
2025-05-09 05:30:08 +02:00
parent 7bb10e7df4
commit 73367bad9e
5322 changed files with 1266973 additions and 313 deletions

View File

@@ -0,0 +1,65 @@
import { FromPathOption, NavigateOptions, PathParamOptions, SearchParamOptions, ToPathOption } from './link.js';
import { Redirect } from './redirect.js';
import { RouteIds } from './routeInfo.js';
import { AnyRouter, RegisteredRouter } from './router.js';
import { UseParamsResult } from './useParams.js';
import { UseSearchResult } from './useSearch.js';
import { Constrain, ConstrainLiteral } from './utils.js';
export type ValidateFromPath<TRouter extends AnyRouter = RegisteredRouter, TFrom = string> = FromPathOption<TRouter, TFrom>;
export type ValidateToPath<TRouter extends AnyRouter = RegisteredRouter, TTo extends string | undefined = undefined, TFrom extends string = string> = ToPathOption<TRouter, TFrom, TTo>;
export type ValidateSearch<TRouter extends AnyRouter = RegisteredRouter, TTo extends string | undefined = undefined, TFrom extends string = string> = SearchParamOptions<TRouter, TFrom, TTo>;
export type ValidateParams<TRouter extends AnyRouter = RegisteredRouter, TTo extends string | undefined = undefined, TFrom extends string = string> = PathParamOptions<TRouter, TFrom, TTo>;
/**
* @internal
*/
export type InferFrom<TOptions, TDefaultFrom extends string = string> = TOptions extends {
from: infer TFrom extends string;
} ? TFrom : TDefaultFrom;
/**
* @internal
*/
export type InferTo<TOptions> = TOptions extends {
to: infer TTo extends string;
} ? TTo : undefined;
/**
* @internal
*/
export type InferMaskTo<TOptions> = TOptions extends {
mask: {
to: infer TTo extends string;
};
} ? TTo : '';
export type InferMaskFrom<TOptions> = TOptions extends {
mask: {
from: infer TFrom extends string;
};
} ? TFrom : string;
export type ValidateNavigateOptions<TRouter extends AnyRouter = RegisteredRouter, TOptions = unknown, TDefaultFrom extends string = string> = Constrain<TOptions, NavigateOptions<TRouter, InferFrom<TOptions, TDefaultFrom>, InferTo<TOptions>, InferMaskFrom<TOptions>, InferMaskTo<TOptions>>>;
export type ValidateNavigateOptionsArray<TRouter extends AnyRouter = RegisteredRouter, TOptions extends ReadonlyArray<any> = ReadonlyArray<unknown>, TDefaultFrom extends string = string> = {
[K in keyof TOptions]: ValidateNavigateOptions<TRouter, TOptions[K], TDefaultFrom>;
};
export type ValidateRedirectOptions<TRouter extends AnyRouter = RegisteredRouter, TOptions = unknown, TDefaultFrom extends string = string> = Constrain<TOptions, Redirect<TRouter, InferFrom<TOptions, TDefaultFrom>, InferTo<TOptions>, InferMaskFrom<TOptions>, InferMaskTo<TOptions>>>;
export type ValidateRedirectOptionsArray<TRouter extends AnyRouter = RegisteredRouter, TOptions extends ReadonlyArray<any> = ReadonlyArray<unknown>, TDefaultFrom extends string = string> = {
[K in keyof TOptions]: ValidateRedirectOptions<TRouter, TOptions[K], TDefaultFrom>;
};
export type ValidateId<TRouter extends AnyRouter = RegisteredRouter, TId extends string = string> = ConstrainLiteral<TId, RouteIds<TRouter['routeTree']>>;
/**
* @internal
*/
export type InferStrict<TOptions> = TOptions extends {
strict: infer TStrict extends boolean;
} ? TStrict : true;
/**
* @internal
*/
export type InferShouldThrow<TOptions> = TOptions extends {
shouldThrow: infer TShouldThrow extends boolean;
} ? TShouldThrow : true;
/**
* @internal
*/
export type InferSelected<TOptions> = TOptions extends {
select: (...args: Array<any>) => infer TSelected;
} ? TSelected : unknown;
export type ValidateUseSearchResult<TOptions, TRouter extends AnyRouter = RegisteredRouter> = UseSearchResult<TRouter, InferFrom<TOptions>, InferStrict<TOptions>, InferSelected<TOptions>>;
export type ValidateUseParamsResult<TOptions, TRouter extends AnyRouter = RegisteredRouter> = Constrain<TOptions, UseParamsResult<TRouter, InferFrom<TOptions>, InferStrict<TOptions>, InferSelected<TOptions>>>;

View File

@@ -0,0 +1 @@
module.exports={A:{D:{"1":"0 9 aB bB cB dB eB fB gB hB iB jB kB lB mB nB oB pB qB rB sB tB uB vB MC wB NC xB yB zB 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AC BC CC DC Q H R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB I PC EC QC RC","2":"1 2 3 4 5 6 7 8 J PB K D E F A B C L M G N O P QB RB SB TB UB","33":"VB WB XB YB ZB"},L:{"1":"I"},B:{"1":"0 9 Q H R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB I","33":"C L M G N O P"},C:{"1":"0 9 kB lB mB nB oB pB qB rB sB tB uB vB MC wB NC xB yB zB 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AC BC CC DC Q H R OC S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB I PC EC QC RC oC pC","2":"1 2 3 4 5 6 7 8 nC LC J PB K D E F A B C L M G N O P QB RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB qC rC"},M:{"1":"EC"},A:{"2":"K D E F A mC","33":"B"},F:{"1":"0 5 6 7 8 RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB kB lB mB nB oB pB qB rB sB tB uB vB wB xB yB zB 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AC BC CC DC Q H R OC S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z","2":"F B C G N O P 4C 5C 6C 7C FC kC 8C GC","33":"1 2 3 4 QB"},K:{"1":"H","2":"A B C FC kC GC"},E:{"1":"VC HC 0C IC WC XC YC ZC aC 1C JC bC cC dC eC fC 2C KC gC hC iC jC","2":"J PB K D E F A B C L M G sC SC tC uC vC wC TC FC GC xC yC zC UC 3C"},G:{"1":"VC HC TD IC WC XC YC ZC aC UD JC bC cC dC eC fC VD KC gC hC iC jC","2":"E SC 9C lC AD BD CD DD ED FD GD HD ID JD KD LD MD ND OD PD QD RD SD UC"},P:{"1":"1 2 3 4 5 6 7 8 J dD eD fD gD hD TC iD jD kD lD mD IC JC KC nD"},I:{"1":"I","2":"LC J XD YD ZD aD lC","33":"bD cD"}},B:6,C:"CSS ::backdrop pseudo-element",D:undefined};

View File

@@ -0,0 +1,94 @@
const description =
' See https://vite.dev/guide/troubleshooting.html#vite-cjs-node-api-deprecated for more details.'
warnCjsUsage()
// type utils
module.exports.defineConfig = (config) => config
// proxy cjs utils (sync functions)
Object.assign(module.exports, require('./dist/node-cjs/publicUtils.cjs'))
// async functions, can be redirect from ESM build
const asyncFunctions = [
'build',
'createServer',
'preview',
'transformWithEsbuild',
'resolveConfig',
'optimizeDeps',
'formatPostcssSourceMap',
'loadConfigFromFile',
'preprocessCSS',
'createBuilder',
'runnerImport',
]
asyncFunctions.forEach((name) => {
module.exports[name] = (...args) =>
import('./dist/node/index.js').then((i) => i[name](...args))
})
// variables and sync functions that cannot be used from cjs build
const disallowedVariables = [
// was not exposed in cjs from the beginning
'parseAst',
'parseAstAsync',
'buildErrorMessage',
'sortUserPlugins',
// Environment API related variables that are too big to include in the cjs build
'DevEnvironment',
'BuildEnvironment',
'createIdResolver',
'createRunnableDevEnvironment',
// can be redirected from ESM, but doesn't make sense as it's Environment API related
'fetchModule',
'moduleRunnerTransform',
// can be exposed, but doesn't make sense as it's Environment API related
'createServerHotChannel',
'createServerModuleRunner',
'createServerModuleRunnerTransport',
'isRunnableDevEnvironment',
]
disallowedVariables.forEach((name) => {
Object.defineProperty(module.exports, name, {
get() {
throw new Error(
`${name} is not available in the CJS build of Vite.` + description,
)
},
})
})
function warnCjsUsage() {
if (process.env.VITE_CJS_IGNORE_WARNING) return
const logLevelIndex = process.argv.findIndex((arg) =>
/^(?:-l|--logLevel)/.test(arg),
)
if (logLevelIndex > 0) {
const logLevelValue = process.argv[logLevelIndex + 1]
if (logLevelValue === 'silent' || logLevelValue === 'error') {
return
}
if (/silent|error/.test(process.argv[logLevelIndex])) {
return
}
}
const yellow = (str) => `\u001b[33m${str}\u001b[39m`
console.warn(
yellow("The CJS build of Vite's Node API is deprecated." + description),
)
if (process.env.VITE_CJS_TRACE) {
const e = {}
const stackTraceLimit = Error.stackTraceLimit
Error.stackTraceLimit = 100
Error.captureStackTrace(e)
Error.stackTraceLimit = stackTraceLimit
console.log(
e.stack
.split('\n')
.slice(1)
.filter((line) => !line.includes('(node:'))
.join('\n'),
)
}
}

View File

@@ -0,0 +1,7 @@
import { AnySchema } from './validators.js';
export declare const defaultParseSearch: (searchStr: string) => AnySchema;
export declare const defaultStringifySearch: (search: Record<string, any>) => string;
export declare function parseSearchWith(parser: (str: string) => any): (searchStr: string) => AnySchema;
export declare function stringifySearchWith(stringify: (search: any) => string, parser?: (str: string) => any): (search: Record<string, any>) => string;
export type SearchSerializer = (searchObj: Record<string, any>) => string;
export type SearchParser = (searchStr: string) => Record<string, any>;

View File

@@ -0,0 +1 @@
{"version":3,"file":"redirect.cjs","sources":["../../src/redirect.ts"],"sourcesContent":["import type { NavigateOptions } from './link'\nimport type { RoutePaths } from './routeInfo'\nimport type { AnyRouter, RegisteredRouter } from './router'\nimport type { PickAsRequired } from './utils'\n\nexport type AnyRedirect = Redirect<any, any, any, any, any>\n\n/**\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RedirectType)\n */\nexport type Redirect<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> | string = '/',\n TTo extends string | undefined = '.',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom,\n TMaskTo extends string = '.',\n> = {\n href?: string\n /**\n * @deprecated Use `statusCode` instead\n **/\n code?: number\n /**\n * The HTTP status code to use when redirecting.\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RedirectType#statuscode-property)\n */\n statusCode?: number\n /**\n * If provided, will throw the redirect object instead of returning it. This can be useful in places where `throwing` in a function might cause it to have a return type of `never`. In that case, you can use `redirect({ throw: true })` to throw the redirect object instead of returning it.\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RedirectType#throw-property)\n */\n throw?: any\n /**\n * The HTTP headers to use when redirecting.\n * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RedirectType#headers-property)\n */\n headers?: HeadersInit\n} & NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>\n\nexport type ResolvedRedirect<\n TRouter extends AnyRouter = RegisteredRouter,\n TFrom extends RoutePaths<TRouter['routeTree']> = '/',\n TTo extends string = '',\n TMaskFrom extends RoutePaths<TRouter['routeTree']> = TFrom,\n TMaskTo extends string = '',\n> = PickAsRequired<\n Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n 'code' | 'statusCode' | 'headers'\n> & {\n href: string\n}\n\nexport function redirect<\n TRouter extends RegisteredRouter,\n const TTo extends string | undefined,\n const TFrom extends string = string,\n const TMaskFrom extends string = TFrom,\n const TMaskTo extends string = '',\n>(\n opts: Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>,\n): Redirect<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> {\n ;(opts as any).isRedirect = true\n opts.statusCode = opts.statusCode || opts.code || 307\n opts.headers = opts.headers || {}\n if (!opts.reloadDocument) {\n opts.reloadDocument = false\n try {\n new URL(`${opts.href}`)\n opts.reloadDocument = true\n } catch {}\n }\n\n if (opts.throw) {\n throw opts\n }\n\n return opts\n}\n\nexport function isRedirect(obj: any): obj is AnyRedirect {\n return !!obj?.isRedirect\n}\n\nexport function isResolvedRedirect(obj: any): obj is ResolvedRedirect {\n return !!obj?.isRedirect && obj.href\n}\n"],"names":[],"mappings":";;AAoDO,SAAS,SAOd,MACmD;AACjD,OAAa,aAAa;AAC5B,OAAK,aAAa,KAAK,cAAc,KAAK,QAAQ;AAC7C,OAAA,UAAU,KAAK,WAAW,CAAC;AAC5B,MAAA,CAAC,KAAK,gBAAgB;AACxB,SAAK,iBAAiB;AAClB,QAAA;AACF,UAAI,IAAI,GAAG,KAAK,IAAI,EAAE;AACtB,WAAK,iBAAiB;AAAA,IAAA,QAChB;AAAA,IAAA;AAAA,EAAC;AAGX,MAAI,KAAK,OAAO;AACR,UAAA;AAAA,EAAA;AAGD,SAAA;AACT;AAEO,SAAS,WAAW,KAA8B;AAChD,SAAA,CAAC,EAAC,2BAAK;AAChB;AAEO,SAAS,mBAAmB,KAAmC;AACpE,SAAO,CAAC,EAAC,2BAAK,eAAc,IAAI;AAClC;;;;"}

View File

@@ -0,0 +1,44 @@
'use strict';
var test = require('tape');
var stringify = require('../');
test('nested', function (t) {
t.plan(1);
var obj = { c: 8, b: [{z:6,y:5,x:4},7], a: 3 };
t.equal(stringify(obj), '{"a":3,"b":[{"x":4,"y":5,"z":6},7],"c":8}');
});
test('cyclic (default)', function (t) {
t.plan(1);
var one = { a: 1 };
var two = { a: 2, one: one };
one.two = two;
try {
stringify(one);
} catch (ex) {
t.equal(ex.toString(), 'TypeError: Converting circular structure to JSON');
}
});
test('cyclic (specifically allowed)', function (t) {
t.plan(1);
var one = { a: 1 };
var two = { a: 2, one: one };
one.two = two;
t.equal(stringify(one, {cycles:true}), '{"a":1,"two":{"a":2,"one":"__cycle__"}}');
});
test('repeated non-cyclic value', function(t) {
t.plan(1);
var one = { x: 1 };
var two = { a: one, b: one };
t.equal(stringify(two), '{"a":{"x":1},"b":{"x":1}}');
});
test('acyclic but with reused obj-property pointers', function (t) {
t.plan(1);
var x = { a: 1 };
var y = { b: x, c: x };
t.equal(stringify(y), '{"b":{"a":1},"c":{"a":1}}');
});

View File

@@ -0,0 +1,12 @@
# These are supported funding model platforms
github: [ljharb]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: npm/minimist
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@@ -0,0 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _classPrivateSetter;
var _assertClassBrand = require("./assertClassBrand.js");
function _classPrivateSetter(privateMap, setter, receiver, value) {
setter((0, _assertClassBrand.default)(privateMap, receiver), value);
return value;
}
//# sourceMappingURL=classPrivateSetter.js.map

View File

@@ -0,0 +1,151 @@
import * as React from 'react'
import { Asset } from './Asset'
import { useRouter } from './useRouter'
import { useRouterState } from './useRouterState'
import type { RouterManagedTag } from '@tanstack/router-core'
export const useTags = () => {
const router = useRouter()
const routeMeta = useRouterState({
select: (state) => {
return state.matches.map((match) => match.meta!).filter(Boolean)
},
})
const meta: Array<RouterManagedTag> = React.useMemo(() => {
const resultMeta: Array<RouterManagedTag> = []
const metaByAttribute: Record<string, true> = {}
let title: RouterManagedTag | undefined
;[...routeMeta].reverse().forEach((metas) => {
;[...metas].reverse().forEach((m) => {
if (!m) return
if (m.title) {
if (!title) {
title = {
tag: 'title',
children: m.title,
}
}
} else {
const attribute = m.name ?? m.property
if (attribute) {
if (metaByAttribute[attribute]) {
return
} else {
metaByAttribute[attribute] = true
}
}
resultMeta.push({
tag: 'meta',
attrs: {
...m,
},
})
}
})
})
if (title) {
resultMeta.push(title)
}
resultMeta.reverse()
return resultMeta
}, [routeMeta])
const links = useRouterState({
select: (state) =>
state.matches
.map((match) => match.links!)
.filter(Boolean)
.flat(1)
.map((link) => ({
tag: 'link',
attrs: {
...link,
},
})) as Array<RouterManagedTag>,
structuralSharing: true as any,
})
const preloadMeta = useRouterState({
select: (state) => {
const preloadMeta: Array<RouterManagedTag> = []
state.matches
.map((match) => router.looseRoutesById[match.routeId]!)
.forEach((route) =>
router.ssr?.manifest?.routes[route.id]?.preloads
?.filter(Boolean)
.forEach((preload) => {
preloadMeta.push({
tag: 'link',
attrs: {
rel: 'modulepreload',
href: preload,
},
})
}),
)
return preloadMeta
},
structuralSharing: true as any,
})
const headScripts = useRouterState({
select: (state) =>
(
state.matches
.map((match) => match.headScripts!)
.flat(1)
.filter(Boolean) as Array<RouterManagedTag>
).map(({ children, ...script }) => ({
tag: 'script',
attrs: {
...script,
},
children,
})),
structuralSharing: true as any,
})
return uniqBy(
[
...meta,
...preloadMeta,
...links,
...headScripts,
] as Array<RouterManagedTag>,
(d) => {
return JSON.stringify(d)
},
)
}
/**
* @description The `HeadContent` component is used to render meta tags, links, and scripts for the current route.
* It should be rendered in the `<head>` of your document.
*/
export function HeadContent() {
const tags = useTags()
return tags.map((tag) => (
<Asset {...tag} key={`tsr-meta-${JSON.stringify(tag)}`} />
))
}
function uniqBy<T>(arr: Array<T>, fn: (item: T) => string) {
const seen = new Set<string>()
return arr.filter((item) => {
const key = fn(item)
if (seen.has(key)) {
return false
}
seen.add(key)
return true
})
}

View File

@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = _classStaticPrivateFieldSpecGet;
var _classApplyDescriptorGet = require("classApplyDescriptorGet");
var _assertClassBrand = require("assertClassBrand");
var _classCheckPrivateStaticFieldDescriptor = require("classCheckPrivateStaticFieldDescriptor");
function _classStaticPrivateFieldSpecGet(receiver, classConstructor, descriptor) {
_assertClassBrand(classConstructor, receiver);
_classCheckPrivateStaticFieldDescriptor(descriptor, "get");
return _classApplyDescriptorGet(receiver, descriptor);
}
//# sourceMappingURL=classStaticPrivateFieldSpecGet.js.map

View File

@@ -0,0 +1,13 @@
/**
* @author Toru Nagashima <https://github.com/mysticatea>
*/
"use strict";
/**
* Check whether a given character is an emoji modifier.
* @param {number} code The character code to check.
* @returns {boolean} `true` if the character is an emoji modifier.
*/
module.exports = function isEmojiModifier(code) {
return code >= 0x1f3fb && code <= 0x1f3ff;
};

View File

@@ -0,0 +1,277 @@
/**
* @fileoverview Rule to flag use of constructors without capital letters
* @author Nicholas C. Zakas
*/
"use strict";
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
const astUtils = require("./utils/ast-utils");
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
const CAPS_ALLOWED = [
"Array",
"Boolean",
"Date",
"Error",
"Function",
"Number",
"Object",
"RegExp",
"String",
"Symbol",
"BigInt",
];
/**
* A reducer function to invert an array to an Object mapping the string form of the key, to `true`.
* @param {Object} map Accumulator object for the reduce.
* @param {string} key Object key to set to `true`.
* @returns {Object} Returns the updated Object for further reduction.
*/
function invert(map, key) {
map[key] = true;
return map;
}
/**
* Creates an object with the cap is new exceptions as its keys and true as their values.
* @param {Object} config Rule configuration
* @returns {Object} Object with cap is new exceptions.
*/
function calculateCapIsNewExceptions(config) {
const capIsNewExceptions = Array.from(
new Set([...config.capIsNewExceptions, ...CAPS_ALLOWED]),
);
return capIsNewExceptions.reduce(invert, {});
}
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
/** @type {import('../shared/types').Rule} */
module.exports = {
meta: {
type: "suggestion",
docs: {
description:
"Require constructor names to begin with a capital letter",
recommended: false,
url: "https://eslint.org/docs/latest/rules/new-cap",
},
schema: [
{
type: "object",
properties: {
newIsCap: {
type: "boolean",
},
capIsNew: {
type: "boolean",
},
newIsCapExceptions: {
type: "array",
items: {
type: "string",
},
},
newIsCapExceptionPattern: {
type: "string",
},
capIsNewExceptions: {
type: "array",
items: {
type: "string",
},
},
capIsNewExceptionPattern: {
type: "string",
},
properties: {
type: "boolean",
},
},
additionalProperties: false,
},
],
defaultOptions: [
{
capIsNew: true,
capIsNewExceptions: CAPS_ALLOWED,
newIsCap: true,
newIsCapExceptions: [],
properties: true,
},
],
messages: {
upper: "A function with a name starting with an uppercase letter should only be used as a constructor.",
lower: "A constructor name should not start with a lowercase letter.",
},
},
create(context) {
const [config] = context.options;
const skipProperties = !config.properties;
const newIsCapExceptions = config.newIsCapExceptions.reduce(invert, {});
const newIsCapExceptionPattern = config.newIsCapExceptionPattern
? new RegExp(config.newIsCapExceptionPattern, "u")
: null;
const capIsNewExceptions = calculateCapIsNewExceptions(config);
const capIsNewExceptionPattern = config.capIsNewExceptionPattern
? new RegExp(config.capIsNewExceptionPattern, "u")
: null;
const listeners = {};
const sourceCode = context.sourceCode;
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
/**
* Get exact callee name from expression
* @param {ASTNode} node CallExpression or NewExpression node
* @returns {string} name
*/
function extractNameFromExpression(node) {
return node.callee.type === "Identifier"
? node.callee.name
: astUtils.getStaticPropertyName(node.callee) || "";
}
/**
* Returns the capitalization state of the string -
* Whether the first character is uppercase, lowercase, or non-alphabetic
* @param {string} str String
* @returns {string} capitalization state: "non-alpha", "lower", or "upper"
*/
function getCap(str) {
const firstChar = str.charAt(0);
const firstCharLower = firstChar.toLowerCase();
const firstCharUpper = firstChar.toUpperCase();
if (firstCharLower === firstCharUpper) {
// char has no uppercase variant, so it's non-alphabetic
return "non-alpha";
}
if (firstChar === firstCharLower) {
return "lower";
}
return "upper";
}
/**
* Check if capitalization is allowed for a CallExpression
* @param {Object} allowedMap Object mapping calleeName to a Boolean
* @param {ASTNode} node CallExpression node
* @param {string} calleeName Capitalized callee name from a CallExpression
* @param {Object} pattern RegExp object from options pattern
* @returns {boolean} Returns true if the callee may be capitalized
*/
function isCapAllowed(allowedMap, node, calleeName, pattern) {
const sourceText = sourceCode.getText(node.callee);
if (allowedMap[calleeName] || allowedMap[sourceText]) {
return true;
}
if (pattern && pattern.test(sourceText)) {
return true;
}
const callee = astUtils.skipChainExpression(node.callee);
if (calleeName === "UTC" && callee.type === "MemberExpression") {
// allow if callee is Date.UTC
return (
callee.object.type === "Identifier" &&
callee.object.name === "Date"
);
}
return skipProperties && callee.type === "MemberExpression";
}
/**
* Reports the given messageId for the given node. The location will be the start of the property or the callee.
* @param {ASTNode} node CallExpression or NewExpression node.
* @param {string} messageId The messageId to report.
* @returns {void}
*/
function report(node, messageId) {
let callee = astUtils.skipChainExpression(node.callee);
if (callee.type === "MemberExpression") {
callee = callee.property;
}
context.report({ node, loc: callee.loc, messageId });
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
if (config.newIsCap) {
listeners.NewExpression = function (node) {
const constructorName = extractNameFromExpression(node);
if (constructorName) {
const capitalization = getCap(constructorName);
const isAllowed =
capitalization !== "lower" ||
isCapAllowed(
newIsCapExceptions,
node,
constructorName,
newIsCapExceptionPattern,
);
if (!isAllowed) {
report(node, "lower");
}
}
};
}
if (config.capIsNew) {
listeners.CallExpression = function (node) {
const calleeName = extractNameFromExpression(node);
if (calleeName) {
const capitalization = getCap(calleeName);
const isAllowed =
capitalization !== "upper" ||
isCapAllowed(
capIsNewExceptions,
node,
calleeName,
capIsNewExceptionPattern,
);
if (!isAllowed) {
report(node, "upper");
}
}
};
}
return listeners;
},
};

View File

@@ -0,0 +1 @@
{"version":3,"names":["addDeprecatedGenerators","PrinterClass","deprecatedBabel7Generators","Noop","TSExpressionWithTypeArguments","node","print","expression","typeParameters","DecimalLiteral","raw","getPossibleRaw","format","minified","undefined","word","value","Object","assign","prototype"],"sources":["../../src/generators/deprecated.ts"],"sourcesContent":["import type Printer from \"../printer\";\nimport type * as t from \"@babel/types\";\n\nexport type DeprecatedBabel7ASTTypes =\n | \"Noop\"\n | \"TSExpressionWithTypeArguments\"\n | \"DecimalLiteral\";\n\nexport function addDeprecatedGenerators(PrinterClass: typeof Printer) {\n // Add Babel 7 generator methods that is removed in Babel 8\n if (!process.env.BABEL_8_BREAKING) {\n const deprecatedBabel7Generators = {\n Noop(this: Printer) {},\n\n TSExpressionWithTypeArguments(\n this: Printer,\n // @ts-ignore(Babel 7 vs Babel 8) Babel 7 AST\n node: t.TSExpressionWithTypeArguments,\n ) {\n this.print(node.expression);\n this.print(node.typeParameters);\n },\n\n DecimalLiteral(this: Printer, node: any) {\n const raw = this.getPossibleRaw(node);\n if (!this.format.minified && raw !== undefined) {\n this.word(raw);\n return;\n }\n this.word(node.value + \"m\");\n },\n } satisfies Record<\n DeprecatedBabel7ASTTypes,\n (this: Printer, node: any) => void\n >;\n Object.assign(PrinterClass.prototype, deprecatedBabel7Generators);\n }\n}\n"],"mappings":";;;;;;AAQO,SAASA,uBAAuBA,CAACC,YAA4B,EAAE;EAEjC;IACjC,MAAMC,0BAA0B,GAAG;MACjCC,IAAIA,CAAA,EAAgB,CAAC,CAAC;MAEtBC,6BAA6BA,CAG3BC,IAAqC,EACrC;QACA,IAAI,CAACC,KAAK,CAACD,IAAI,CAACE,UAAU,CAAC;QAC3B,IAAI,CAACD,KAAK,CAACD,IAAI,CAACG,cAAc,CAAC;MACjC,CAAC;MAEDC,cAAcA,CAAgBJ,IAAS,EAAE;QACvC,MAAMK,GAAG,GAAG,IAAI,CAACC,cAAc,CAACN,IAAI,CAAC;QACrC,IAAI,CAAC,IAAI,CAACO,MAAM,CAACC,QAAQ,IAAIH,GAAG,KAAKI,SAAS,EAAE;UAC9C,IAAI,CAACC,IAAI,CAACL,GAAG,CAAC;UACd;QACF;QACA,IAAI,CAACK,IAAI,CAACV,IAAI,CAACW,KAAK,GAAG,GAAG,CAAC;MAC7B;IACF,CAGC;IACDC,MAAM,CAACC,MAAM,CAACjB,YAAY,CAACkB,SAAS,EAAEjB,0BAA0B,CAAC;EACnE;AACF","ignoreList":[]}