@shopify/theme-check-common
Advanced tools
Comparing version 1.20.1 to 1.21.0
# @shopify/theme-check-common | ||
## 1.21.0 | ||
### Minor Changes | ||
- 772a1ce: Update `translation-key-exists` check and intelligent code completion to always stay up-to-date with Shopify translation keys | ||
### Patch Changes | ||
- b05a6a8: Add support for the following Language Server configurations: | ||
- `themeCheck.checkOnOpen` | ||
- `themeCheck.checkOnSave` | ||
- `themeCheck.checkOnChange` | ||
This is mostly for backward compatibility and to not be annoying :) | ||
## 1.20.1 | ||
@@ -4,0 +20,0 @@ |
@@ -7,3 +7,3 @@ import { JsonSchemaValidators } from './types'; | ||
isAugmented: boolean; | ||
validateSectionSchema: () => Promise<import("./types").ValidateFunction<unknown>>; | ||
validateSectionSchema: import("./utils").MemoedFunction<() => Promise<import("./types").ValidateFunction<unknown>>>; | ||
} |
@@ -1,2 +0,2 @@ | ||
import { FilterEntry, ObjectEntry, TagEntry, ThemeDocset } from './types'; | ||
import { FilterEntry, ObjectEntry, TagEntry, ThemeDocset, Translations } from './types'; | ||
export declare class AugmentedThemeDocset implements ThemeDocset { | ||
@@ -6,5 +6,6 @@ private themeDocset; | ||
isAugmented: boolean; | ||
filters: () => Promise<FilterEntry[]>; | ||
objects: () => Promise<ObjectEntry[]>; | ||
tags: () => Promise<TagEntry[]>; | ||
filters: import("./utils").MemoedFunction<() => Promise<FilterEntry[]>>; | ||
objects: import("./utils").MemoedFunction<() => Promise<ObjectEntry[]>>; | ||
tags: import("./utils").MemoedFunction<() => Promise<TagEntry[]>>; | ||
systemTranslations: import("./utils").MemoedFunction<() => Promise<Translations>>; | ||
} |
@@ -64,2 +64,5 @@ "use strict"; | ||
}); | ||
this.systemTranslations = (0, utils_1.memo)(async () => { | ||
return this.themeDocset.systemTranslations(); | ||
}); | ||
} | ||
@@ -66,0 +69,0 @@ } |
@@ -14,71 +14,2 @@ import { ConfigTarget, JSONCheckDefinition, LiquidCheckDefinition } from '../types'; | ||
severity: import("../types").Severity; | ||
type: import("../types").SourceCodeType.JSON; | ||
docs: { | ||
description: string; | ||
recommended?: boolean | undefined; | ||
url?: string | undefined; | ||
}; | ||
schema: import("../types").Schema; | ||
targets?: ConfigTarget[] | undefined; | ||
deprecated?: boolean | undefined; | ||
replacedBy?: boolean | undefined; | ||
}; | ||
create(context: { | ||
report(problem: { | ||
message: string; | ||
startIndex: number; | ||
endIndex: number; | ||
fix?: ((corrector: import("..").JSONCorrector) => void) | undefined; | ||
suggest?: { | ||
message: string; | ||
fix: (corrector: import("..").JSONCorrector) => void; | ||
}[] | undefined; | ||
}): void; | ||
relativePath(absolutePath: string): string; | ||
absolutePath(relativePath: string): string; | ||
file: { | ||
absolutePath: string; | ||
version?: number | undefined; | ||
source: string; | ||
type: import("../types").SourceCodeType.JSON; | ||
ast: Error | import("../types").JSONNode; | ||
}; | ||
} & import("../types").Dependencies & { | ||
settings: import("../types").Settings<import("../types").Schema>; | ||
}): Partial<Partial<{ | ||
Object: import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Object">; | ||
Array: import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Array">; | ||
Property: import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Property">; | ||
Identifier: import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Identifier">; | ||
Literal: import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Literal">; | ||
} & { | ||
"Object:exit": import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Object">; | ||
"Array:exit": import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Array">; | ||
"Property:exit": import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Property">; | ||
"Identifier:exit": import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Identifier">; | ||
"Literal:exit": import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Literal">; | ||
} & { | ||
onCodePathStart(file: { | ||
absolutePath: string; | ||
version?: number | undefined; | ||
source: string; | ||
type: import("../types").SourceCodeType.JSON; | ||
ast: Error | import("../types").JSONNode; | ||
}): Promise<void>; | ||
onCodePathEnd(file: { | ||
absolutePath: string; | ||
version?: number | undefined; | ||
source: string; | ||
type: import("../types").SourceCodeType.JSON; | ||
ast: Error | import("../types").JSONNode; | ||
} & { | ||
ast: import("../types").JSONNode; | ||
}): Promise<void>; | ||
}>>; | ||
} | { | ||
meta: { | ||
name: string; | ||
code: string; | ||
aliases?: string[] | undefined; | ||
severity: import("../types").Severity; | ||
type: import("../types").SourceCodeType.LiquidHtml; | ||
@@ -209,2 +140,71 @@ docs: { | ||
}>>; | ||
} | { | ||
meta: { | ||
name: string; | ||
code: string; | ||
aliases?: string[] | undefined; | ||
severity: import("../types").Severity; | ||
type: import("../types").SourceCodeType.JSON; | ||
docs: { | ||
description: string; | ||
recommended?: boolean | undefined; | ||
url?: string | undefined; | ||
}; | ||
schema: import("../types").Schema; | ||
targets?: ConfigTarget[] | undefined; | ||
deprecated?: boolean | undefined; | ||
replacedBy?: boolean | undefined; | ||
}; | ||
create(context: { | ||
report(problem: { | ||
message: string; | ||
startIndex: number; | ||
endIndex: number; | ||
fix?: ((corrector: import("..").JSONCorrector) => void) | undefined; | ||
suggest?: { | ||
message: string; | ||
fix: (corrector: import("..").JSONCorrector) => void; | ||
}[] | undefined; | ||
}): void; | ||
relativePath(absolutePath: string): string; | ||
absolutePath(relativePath: string): string; | ||
file: { | ||
absolutePath: string; | ||
version?: number | undefined; | ||
source: string; | ||
type: import("../types").SourceCodeType.JSON; | ||
ast: Error | import("../types").JSONNode; | ||
}; | ||
} & import("../types").Dependencies & { | ||
settings: import("../types").Settings<import("../types").Schema>; | ||
}): Partial<Partial<{ | ||
Object: import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Object">; | ||
Property: import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Property">; | ||
Identifier: import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Identifier">; | ||
Array: import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Array">; | ||
Literal: import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Literal">; | ||
} & { | ||
"Object:exit": import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Object">; | ||
"Property:exit": import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Property">; | ||
"Identifier:exit": import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Identifier">; | ||
"Array:exit": import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Array">; | ||
"Literal:exit": import("../types").CheckNodeMethod<import("../types").SourceCodeType.JSON, "Literal">; | ||
} & { | ||
onCodePathStart(file: { | ||
absolutePath: string; | ||
version?: number | undefined; | ||
source: string; | ||
type: import("../types").SourceCodeType.JSON; | ||
ast: Error | import("../types").JSONNode; | ||
}): Promise<void>; | ||
onCodePathEnd(file: { | ||
absolutePath: string; | ||
version?: number | undefined; | ||
source: string; | ||
type: import("../types").SourceCodeType.JSON; | ||
ast: Error | import("../types").JSONNode; | ||
} & { | ||
ast: import("../types").JSONNode; | ||
}): Promise<void>; | ||
}>>; | ||
})[]; |
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.TranslationKeyExists = void 0; | ||
const types_1 = require("../../types"); | ||
const shopify_translation_keys_json_1 = __importDefault(require("./shopify-translation-keys.json")); | ||
function keyExists(key, pointer) { | ||
@@ -72,5 +68,8 @@ for (const token of key.split('.')) { | ||
async onCodePathEnd() { | ||
var _a; | ||
const defaultTranslations = await context.getDefaultTranslations(); | ||
const defaultLocale = await context.getDefaultLocale(); | ||
if (!defaultTranslations) | ||
const systemTranslations = await ((_a = context.themeDocset) === null || _a === void 0 ? void 0 : _a.systemTranslations()); | ||
const systemTranslationsKeys = Object.keys(systemTranslations !== null && systemTranslations !== void 0 ? systemTranslations : {}); | ||
if (!defaultTranslations && systemTranslationsKeys.length === 0) | ||
return; | ||
@@ -80,3 +79,3 @@ nodes.forEach(({ translationKey, startIndex, endIndex }) => { | ||
keyExists(translationKey, schemaLocales) || | ||
shopify_translation_keys_json_1.default.includes(translationKey)) { | ||
systemTranslationsKeys.includes(translationKey)) { | ||
return; | ||
@@ -83,0 +82,0 @@ } |
@@ -0,1 +1,2 @@ | ||
import { Translations } from 'src'; | ||
/** | ||
@@ -13,2 +14,4 @@ * Shopify themes docset. | ||
tags(): Promise<TagEntry[]>; | ||
/** Returns system translations available on themes. */ | ||
systemTranslations(): Promise<Translations>; | ||
} | ||
@@ -15,0 +18,0 @@ /** |
import { ArgumentTypes } from './types'; | ||
export type MemoedFunction<F extends (...args: any[]) => any> = { | ||
/** Only the first call is cached */ | ||
(...args: ArgumentTypes<F>): ReturnType<F>; | ||
/** Clear cache */ | ||
clearCache(): void; | ||
}; | ||
/** Returns a cached version of a function. Only caches one result. */ | ||
export declare function memo<F extends (...args: any[]) => any>(fn: F): (...args: ArgumentTypes<F>) => ReturnType<F>; | ||
export declare function memo<F extends (...args: any[]) => any>(fn: F): MemoedFunction<F>; | ||
/** | ||
@@ -5,0 +11,0 @@ * Returns a function that is cached-by-keyFn(argument) |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.memoize = exports.memo = void 0; | ||
const Unset = Symbol('Unset'); | ||
/** Returns a cached version of a function. Only caches one result. */ | ||
function memo(fn) { | ||
let cachedValue; | ||
return (...args) => { | ||
if (!cachedValue) { | ||
let cachedValue = Unset; | ||
const memoedFunction = (...args) => { | ||
if (cachedValue === Unset) { | ||
cachedValue = fn(...args); | ||
@@ -13,2 +14,6 @@ } | ||
}; | ||
memoedFunction.clearCache = () => { | ||
cachedValue = Unset; | ||
}; | ||
return memoedFunction; | ||
} | ||
@@ -15,0 +20,0 @@ exports.memo = memo; |
{ | ||
"name": "@shopify/theme-check-common", | ||
"version": "1.20.1", | ||
"version": "1.21.0", | ||
"license": "MIT", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/Shopify/theme-tools/blob/main/packages/theme-check-common/README.md", |
@@ -13,2 +13,3 @@ import { describe, beforeEach, it, expect } from 'vitest'; | ||
tags: async () => [], | ||
systemTranslations: async () => ({}), | ||
}); | ||
@@ -15,0 +16,0 @@ }); |
@@ -1,2 +0,2 @@ | ||
import { FilterEntry, ObjectEntry, TagEntry, ThemeDocset } from './types'; | ||
import { FilterEntry, ObjectEntry, TagEntry, ThemeDocset, Translations } from './types'; | ||
import { memo } from './utils'; | ||
@@ -69,2 +69,6 @@ | ||
}); | ||
systemTranslations = memo(async (): Promise<Translations> => { | ||
return this.themeDocset.systemTranslations(); | ||
}); | ||
} |
import { LiquidCheckDefinition, Severity, SourceCodeType } from '../../types'; | ||
import shopifyTranslationKeys from './shopify-translation-keys.json'; | ||
@@ -79,4 +78,7 @@ function keyExists(key: string, pointer: any) { | ||
const defaultLocale = await context.getDefaultLocale(); | ||
if (!defaultTranslations) return; | ||
const systemTranslations = await context.themeDocset?.systemTranslations(); | ||
const systemTranslationsKeys = Object.keys(systemTranslations ?? {}); | ||
if (!defaultTranslations && systemTranslationsKeys.length === 0) return; | ||
nodes.forEach(({ translationKey, startIndex, endIndex }) => { | ||
@@ -86,3 +88,3 @@ if ( | ||
keyExists(translationKey, schemaLocales) || | ||
shopifyTranslationKeys.includes(translationKey) | ||
systemTranslationsKeys.includes(translationKey) | ||
) { | ||
@@ -89,0 +91,0 @@ return; |
@@ -191,2 +191,5 @@ import { | ||
}, | ||
async systemTranslations() { | ||
return { 'shopify.sentence.words_connector': ', ' }; | ||
}, | ||
}, | ||
@@ -193,0 +196,0 @@ }; |
@@ -0,1 +1,3 @@ | ||
import { Translations } from 'src'; | ||
/** | ||
@@ -16,2 +18,5 @@ * Shopify themes docset. | ||
tags(): Promise<TagEntry[]>; | ||
/** Returns system translations available on themes. */ | ||
systemTranslations(): Promise<Translations>; | ||
} | ||
@@ -18,0 +23,0 @@ |
import { ArgumentTypes } from './types'; | ||
export type MemoedFunction<F extends (...args: any[]) => any> = { | ||
/** Only the first call is cached */ | ||
(...args: ArgumentTypes<F>): ReturnType<F>; | ||
/** Clear cache */ | ||
clearCache(): void; | ||
}; | ||
const Unset = Symbol('Unset'); | ||
/** Returns a cached version of a function. Only caches one result. */ | ||
export function memo<F extends (...args: any[]) => any>( | ||
fn: F, | ||
): (...args: ArgumentTypes<F>) => ReturnType<F> { | ||
let cachedValue: ReturnType<F>; | ||
export function memo<F extends (...args: any[]) => any>(fn: F): MemoedFunction<F> { | ||
let cachedValue: ReturnType<F> | typeof Unset = Unset; | ||
return (...args: ArgumentTypes<F>) => { | ||
if (!cachedValue) { | ||
const memoedFunction = (...args: ArgumentTypes<F>) => { | ||
if (cachedValue === Unset) { | ||
cachedValue = fn(...args); | ||
} | ||
return cachedValue; | ||
return cachedValue as ReturnType<F>; | ||
}; | ||
memoedFunction.clearCache = () => { | ||
cachedValue = Unset; | ||
}; | ||
return memoedFunction; | ||
} | ||
@@ -16,0 +29,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
719989
316
13843