Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@shopify/theme-check-common

Package Overview
Dependencies
Maintainers
24
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@shopify/theme-check-common - npm Package Compare versions

Comparing version 2.4.0 to 2.5.0

33

CHANGELOG.md
# @shopify/theme-check-common
## 2.5.0
### Minor Changes
- 03b41e1: Breaking: `jsonValidationSet`'s schemas public API change
Now takes a function of the following signature:
```ts
interface JsonValidationSet = {
schemas: (context: 'theme' | 'app') => Promise<SchemaDefinition[]>
}
```
Reason being we want to support `fileMatch` overloading of `blocks/*.liquid` files and we needed a way to identify which context you're in.
Unfortunately, the JSON schema for `blocks/*.liquid` files in theme app extensions isn't the same one we have in themes. There doesn't seem to be a way to unify them either.
- 03b41e1: Theme Check Config files now accept the `context` property
In your `.theme-check.yml` files, you can set the `context` property to `theme` or `app`. By default, it's `theme`. The `theme-check:theme-app-extension` config sets it to `app`.
You shouldn't need to care about this. It's there so we can do contextual things internally.
- 03b41e1: Add support for the schemas manifest on Shopify/theme-liquid-docs
Shopify/theme-liquid-docs now supports composable JSON schemas (with relative paths). To solve the `blocks/*.liquid` file match JSON schema overload depending on the context (`app` or `theme`), we defined two manifests that describe the schemas required by your solution and define the fileMatch rules:
- [manifest_theme.json](https://github.com/Shopify/theme-liquid-docs/blob/main/schemas/manifest_theme.json)
- [manifest_theme_app_extension.json](https://github.com/Shopify/theme-liquid-docs/blob/main/schemas/manifest_theme.json)
`@shopify/theme-check-docs-updater` now reads those manifests and downloads the tree of dependency that they require. We will no longer need to make new theme-tools releases whenever we add new schemas. We'll be able to dev them and their file associations directly from Shopify/theme-liquid-docs and have downstream consumers updated automatically (the same way docs are automatically updated).
## 2.4.0

@@ -4,0 +37,0 @@

2

dist/index.js

@@ -62,3 +62,3 @@ "use strict";

if (dependencies.jsonValidationSet) {
const jsonValidator = new JSONValidator_1.JSONValidator(dependencies.jsonValidationSet);
const jsonValidator = new JSONValidator_1.JSONValidator(await dependencies.jsonValidationSet.schemas(config.context));
validateJSON = jsonValidator.validate.bind(jsonValidator);

@@ -65,0 +65,0 @@ }

@@ -1,7 +0,6 @@

import { JsonValidationSet, SourceCodeType, ValidateJSON } from './types';
import { SchemaDefinition, SourceCodeType, ValidateJSON } from './types';
export declare class JSONValidator {
private jsonValidationSet;
private service;
private schemas;
constructor(jsonValidationSet: JsonValidationSet);
constructor(schemas: SchemaDefinition[]);
/**

@@ -8,0 +7,0 @@ * Will return an array of diagnostics for the given source code and JSON string.

@@ -7,4 +7,3 @@ "use strict";

class JSONValidator {
constructor(jsonValidationSet) {
this.jsonValidationSet = jsonValidationSet;
constructor(schemas) {
/**

@@ -30,9 +29,14 @@ * Will return an array of diagnostics for the given source code and JSON string.

};
this.jsonValidationSet = jsonValidationSet;
this.schemas = (0, utils_1.indexBy)((x) => x.uri, this.jsonValidationSet.schemas);
this.schemas = (0, utils_1.indexBy)((x) => x.uri, schemas);
this.service = (0, vscode_json_languageservice_1.getLanguageService)({
schemaRequestService: this.getSchemaForURI.bind(this),
workspaceContext: {
resolveRelativePath: (relativePath, resource) => {
const url = new URL(relativePath, resource);
return url.toString();
},
},
});
this.service.configure({
schemas: this.jsonValidationSet.schemas.map((schemaDefinition) => ({
schemas: schemas.map((schemaDefinition) => ({
uri: schemaDefinition.uri,

@@ -45,6 +49,6 @@ fileMatch: schemaDefinition.fileMatch,

var _a;
const promise = (_a = this.schemas[uri]) === null || _a === void 0 ? void 0 : _a.schema;
if (!promise)
const schema = (_a = this.schemas[uri]) === null || _a === void 0 ? void 0 : _a.schema;
if (!schema)
return `No schema for '${uri}' found`;
return promise;
return schema;
}

@@ -51,0 +55,0 @@ }

@@ -11,2 +11,4 @@ import { NodeTypes as LiquidHtmlNodeTypes, LiquidHtmlNode } from '@shopify/liquid-html-parser';

export declare const isPropertyNode: (node?: ASTNode) => node is PropertyNode;
export declare const Modes: readonly ["theme", "app"];
export type Mode = (typeof Modes)[number];
export type Theme = SourceCode<SourceCodeType>[];

@@ -66,2 +68,3 @@ export type SourceCode<T = SourceCodeType> = T extends SourceCodeType ? {

export interface Config {
context: Mode;
settings: ChecksSettings;

@@ -68,0 +71,0 @@ checks: CheckDefinition<SourceCodeType, Schema>[];

@@ -17,3 +17,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.ConfigTarget = exports.Severity = exports.LiquidHtmlNodeTypes = exports.SourceCodeType = exports.isPropertyNode = exports.isArrayNode = exports.isObjectNode = void 0;
exports.ConfigTarget = exports.Severity = exports.LiquidHtmlNodeTypes = exports.SourceCodeType = exports.Modes = exports.isPropertyNode = exports.isArrayNode = exports.isObjectNode = void 0;
const liquid_html_parser_1 = require("@shopify/liquid-html-parser");

@@ -29,2 +29,3 @@ Object.defineProperty(exports, "LiquidHtmlNodeTypes", { enumerable: true, get: function () { return liquid_html_parser_1.NodeTypes; } });

exports.isPropertyNode = isPropertyNode;
exports.Modes = ['theme', 'app'];
var SourceCodeType;

@@ -31,0 +32,0 @@ (function (SourceCodeType) {

@@ -1,2 +0,2 @@

import { Translations } from '..';
import { Mode, Translations } from '..';
/**

@@ -22,4 +22,4 @@ * Shopify themes docset.

uri: JSONSchemaURI;
/** A promise that returns a JSON Schema as string */
schema: Promise<string>;
/** A JSON Schema as string */
schema: string;
/**

@@ -36,3 +36,3 @@ * When absent, does not match on file. Assumed to be used by other

/** All relevant SchemaDefinitions. */
schemas: SchemaDefinition[];
schemas: (mode: Mode) => Promise<SchemaDefinition[]>;
}

@@ -39,0 +39,0 @@ export interface DocsetEntry {

@@ -29,2 +29,2 @@ import { ArgumentTypes } from './types';

*/
export declare function memoize<AT, RT, F extends (arg: AT) => RT>(fn: F, keyFn: (arg: AT) => string): (arg: AT) => RT;
export declare function memoize<AT, F extends (arg: AT) => any, RT extends ReturnType<F>>(fn: F, keyFn: (arg: AT) => string): (arg: AT) => RT;
{
"name": "@shopify/theme-check-common",
"version": "2.4.0",
"version": "2.5.0",
"license": "MIT",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -13,3 +13,3 @@ import { expect, describe, it } from 'vitest';

const offenses = await runJSONCheck(ValidJSON, invalidJson, 'file.json', {
jsonValidationSet: { schemas: [] },
jsonValidationSet: { schemas: async () => [] },
});

@@ -32,3 +32,3 @@

const offenses = await runJSONCheck(ValidJSON, invalidJson, 'file.json', {
jsonValidationSet: { schemas: [] },
jsonValidationSet: { schemas: async () => [] },
});

@@ -50,3 +50,3 @@ expect(offenses).to.have.length(1);

const offenses = await runJSONCheck(ValidJSON, invalidJson, 'file.json', {
jsonValidationSet: { schemas: [] },
jsonValidationSet: { schemas: async () => [] },
});

@@ -78,6 +78,6 @@ expect(offenses).to.have.length(1);

jsonValidationSet: {
schemas: [
schemas: async () => [
{
uri: 'https://shopify.dev/some-schema.json',
schema: Promise.resolve(basicJsonSchema),
schema: basicJsonSchema,
fileMatch: ['file.json'],

@@ -84,0 +84,0 @@ },

@@ -41,6 +41,6 @@ import lodashSet from 'lodash/set';

jsonValidationSet: {
schemas: [
schemas: async () => [
{
uri: 'https://shopify.dev/some-schema.json',
schema: Promise.resolve(JSON.stringify(MockSectionSchemaJsonSchema)),
schema: JSON.stringify(MockSectionSchemaJsonSchema),
fileMatch: ['**/sections/*.liquid'],

@@ -47,0 +47,0 @@ },

@@ -191,2 +191,3 @@ import { expect, describe, it } from 'vitest';

return {
context: 'theme',
settings: {

@@ -193,0 +194,0 @@ MockCheck: {

@@ -63,3 +63,5 @@ import {

if (dependencies.jsonValidationSet) {
const jsonValidator = new JSONValidator(dependencies.jsonValidationSet);
const jsonValidator = new JSONValidator(
await dependencies.jsonValidationSet.schemas(config.context),
);
validateJSON = jsonValidator.validate.bind(jsonValidator);

@@ -66,0 +68,0 @@ }

import { LanguageService, TextDocument, getLanguageService } from 'vscode-json-languageservice';
import { JsonValidationSet, SchemaDefinition, SourceCodeType, ValidateJSON } from './types';
import { SchemaDefinition, SourceCodeType, ValidateJSON } from './types';
import { indexBy } from './utils';

@@ -9,10 +9,15 @@

constructor(private jsonValidationSet: JsonValidationSet) {
this.jsonValidationSet = jsonValidationSet;
this.schemas = indexBy((x) => x.uri, this.jsonValidationSet.schemas);
constructor(schemas: SchemaDefinition[]) {
this.schemas = indexBy((x) => x.uri, schemas);
this.service = getLanguageService({
schemaRequestService: this.getSchemaForURI.bind(this),
workspaceContext: {
resolveRelativePath: (relativePath, resource) => {
const url = new URL(relativePath, resource);
return url.toString();
},
},
});
this.service.configure({
schemas: this.jsonValidationSet.schemas.map((schemaDefinition) => ({
schemas: schemas.map((schemaDefinition) => ({
uri: schemaDefinition.uri,

@@ -51,6 +56,6 @@ fileMatch: schemaDefinition.fileMatch,

private async getSchemaForURI(uri: string): Promise<string> {
const promise = this.schemas[uri]?.schema;
if (!promise) return `No schema for '${uri}' found`;
return promise;
const schema = this.schemas[uri]?.schema;
if (!schema) return `No schema for '${uri}' found`;
return schema;
}
}

@@ -56,2 +56,3 @@ import {

const config: Config = {
context: 'theme',
settings: { ...checkSettings },

@@ -58,0 +59,0 @@ checks: checks,

@@ -24,2 +24,4 @@ import { NodeTypes as LiquidHtmlNodeTypes, LiquidHtmlNode } from '@shopify/liquid-html-parser';

export const Modes = ['theme', 'app'] as const;
export type Mode = (typeof Modes)[number];
export type Theme = SourceCode<SourceCodeType>[];

@@ -102,2 +104,8 @@

export interface Config {
// I know, it's `context` in the config and `Mode` in the code...
// We already have something named "Context" internally when you're writing a check.
// I don't like "Mode" as a public API in the configs. Context sounds more Shopify-y.
// So we have `context: theme` and `context: app` as valid .theme-check.yml configs.
// I think it's rather obvious what they mean.
context: Mode;
settings: ChecksSettings;

@@ -104,0 +112,0 @@ checks: CheckDefinition<SourceCodeType, Schema>[];

@@ -1,2 +0,2 @@

import { Translations } from '..';
import { Mode, Translations } from '..';

@@ -30,4 +30,4 @@ /**

/** A promise that returns a JSON Schema as string */
schema: Promise<string>;
/** A JSON Schema as string */
schema: string;

@@ -46,3 +46,3 @@ /**

/** All relevant SchemaDefinitions. */
schemas: SchemaDefinition[];
schemas: (mode: Mode) => Promise<SchemaDefinition[]>;
}

@@ -49,0 +49,0 @@

@@ -49,3 +49,6 @@ import { ArgumentTypes } from './types';

*/
export function memoize<AT, RT, F extends (arg: AT) => RT>(fn: F, keyFn: (arg: AT) => string) {
export function memoize<AT, F extends (arg: AT) => any, RT extends ReturnType<F>>(
fn: F,
keyFn: (arg: AT) => string,
) {
const cache: Record<string, RT> = {};

@@ -52,0 +55,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

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc