diff --git a/graphql.config.ts b/graphql.config.ts index 5396c4d64bc..175f82c7585 100644 --- a/graphql.config.ts +++ b/graphql.config.ts @@ -14,7 +14,7 @@ function projectFactory(name: string, schemaName: string, project: string = 'app { add: { content: - "/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/ban-types, @typescript-eslint/no-explicit-any, tsdoc/syntax, @typescript-eslint/no-duplicate-type-constituents, @typescript-eslint/no-redundant-type-constituents, @nx/enforce-module-boundaries */\nimport {JsonMapType} from '@shopify/cli-kit/node/toml'", + "/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any, tsdoc/syntax, @typescript-eslint/no-duplicate-type-constituents, @typescript-eslint/no-redundant-type-constituents, @nx/enforce-module-boundaries */\nimport {JsonMapType} from '@shopify/cli-kit/node/toml'", }, }, ], @@ -35,7 +35,7 @@ function projectFactory(name: string, schemaName: string, project: string = 'app { add: { content: - "/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/ban-types, @typescript-eslint/no-duplicate-type-constituents, @typescript-eslint/no-redundant-type-constituents, @nx/enforce-module-boundaries */\nimport {JsonMapType} from '@shopify/cli-kit/node/toml'", + "/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-duplicate-type-constituents, @typescript-eslint/no-redundant-type-constituents, @nx/enforce-module-boundaries */\nimport {JsonMapType} from '@shopify/cli-kit/node/toml'", }, }, { diff --git a/packages/app/src/cli/api/graphql/admin/generated/types.d.ts b/packages/app/src/cli/api/graphql/admin/generated/types.d.ts index 98ff1c678d8..75ed424aaf1 100644 --- a/packages/app/src/cli/api/graphql/admin/generated/types.d.ts +++ b/packages/app/src/cli/api/graphql/admin/generated/types.d.ts @@ -1,53 +1,52 @@ -/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any, tsdoc/syntax */ +/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any, tsdoc/syntax, @typescript-eslint/no-duplicate-type-constituents, @typescript-eslint/no-redundant-type-constituents, @nx/enforce-module-boundaries */ import {JsonMapType} from '@shopify/cli-kit/node/toml' - -export type Maybe = T | null -export type InputMaybe = Maybe -export type Exact = {[K in keyof T]: T[K]} -export type MakeOptional = Omit & {[SubKey in K]?: Maybe} -export type MakeMaybe = Omit & {[SubKey in K]: Maybe} -export type MakeEmpty = {[_ in K]?: never} -export type Incremental = T | {[P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never} +export type Maybe = T | null; +export type InputMaybe = Maybe; +export type Exact = { [K in keyof T]: T[K] }; +export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; +export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; +export type MakeEmpty = { [_ in K]?: never }; +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { - ID: {input: string; output: string} - String: {input: string; output: string} - Boolean: {input: boolean; output: boolean} - Int: {input: number; output: number} - Float: {input: number; output: number} + ID: { input: string; output: string; } + String: { input: string; output: string; } + Boolean: { input: boolean; output: boolean; } + Int: { input: number; output: number; } + Float: { input: number; output: number; } /** * An Amazon Web Services Amazon Resource Name (ARN), including the Region and account ID. * For more information, refer to [Amazon Resource Names](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). */ - ARN: {input: any; output: any} + ARN: { input: any; output: any; } /** * Represents non-fractional signed whole numeric values. Since the value may * exceed the size of a 32-bit integer, it's encoded as a string. */ - BigInt: {input: any; output: any} + BigInt: { input: any; output: any; } /** * A string containing a hexadecimal representation of a color. * * For example, "#6A8D48". */ - Color: {input: any; output: any} + Color: { input: any; output: any; } /** * Represents an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)-encoded date string. * For example, September 7, 2019 is represented as `"2019-07-16"`. */ - Date: {input: any; output: any} + Date: { input: any; output: any; } /** * Represents an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)-encoded date and time string. * For example, 3:50 pm on September 7, 2019 in the time zone of UTC (Coordinated Universal Time) is * represented as `"2019-09-07T15:50:00Z`". */ - DateTime: {input: any; output: any} + DateTime: { input: any; output: any; } /** * A signed decimal number, which supports arbitrary precision and is serialized as a string. * * Example values: `"29.99"`, `"29.999"`. */ - Decimal: {input: any; output: any} + Decimal: { input: any; output: any; } /** * A string containing a strict subset of HTML code. Non-allowed tags will be stripped out. * Allowed tags: @@ -63,14 +62,14 @@ export type Scalars = { * * Example value: `"Your current domain is example.myshopify.com."` */ - FormattedString: {input: any; output: any} + FormattedString: { input: any; output: any; } /** * A string containing HTML code. Refer to the [HTML spec](https://html.spec.whatwg.org/#elements-3) for a * complete list of HTML elements. * * Example value: `"

Grey cotton knit sweater.

"` */ - HTML: {input: any; output: any} + HTML: { input: any; output: any; } /** * A [JSON](https://www.json.org/json-en.html) object. * @@ -86,16 +85,16 @@ export type Scalars = { * } * }` */ - JSON: {input: JsonMapType | string; output: JsonMapType} + JSON: { input: JsonMapType | string; output: JsonMapType; } /** A monetary value string without a currency symbol or code. Example value: `"100.57"`. */ - Money: {input: any; output: any} + Money: { input: any; output: any; } /** * Represents a unique identifier in the Storefront API. A `StorefrontID` value can * be used wherever an ID is expected in the Storefront API. * * Example value: `"Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0LzEwMDc5Nzg1MTAw"`. */ - StorefrontID: {input: any; output: any} + StorefrontID: { input: any; output: any; } /** * Represents an [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) and * [RFC 3987](https://datatracker.ietf.org/doc/html/rfc3987)-compliant URI string. @@ -103,20 +102,20 @@ export type Scalars = { * For example, `"https://example.myshopify.com"` is a valid URL. It includes a scheme (`https`) and a host * (`example.myshopify.com`). */ - URL: {input: string; output: string} + URL: { input: string; output: string; } /** * An unsigned 64-bit integer. Represents whole numeric values between 0 and 2^64 - 1 encoded as a string of base-10 digits. * * Example value: `"50"`. */ - UnsignedInt64: {input: any; output: any} + UnsignedInt64: { input: any; output: any; } /** * Time between UTC time and a location's observed time, in the format `"+HH:MM"` or `"-HH:MM"`. * * Example value: `"-07:00"`. */ - UtcOffset: {input: any; output: any} -} + UtcOffset: { input: any; output: any; } +}; /** Metafield access permissions for the Admin API. */ export type MetafieldAdminAccess = @@ -129,7 +128,7 @@ export type MetafieldAdminAccess = /** The merchant and other apps have read-only access. */ | 'PUBLIC_READ' /** The merchant and other apps have read and write access. */ - | 'PUBLIC_READ_WRITE' + | 'PUBLIC_READ_WRITE'; /** Metafield access permissions for the Customer Account API. */ export type MetafieldCustomerAccountAccess = @@ -138,7 +137,7 @@ export type MetafieldCustomerAccountAccess = /** Read-only access. */ | 'READ' /** Read and write access. */ - | 'READ_WRITE' + | 'READ_WRITE'; /** Possible types of a metafield's owner resource. */ export type MetafieldOwnerType = @@ -195,14 +194,14 @@ export type MetafieldOwnerType = /** The Shop metafield owner type. */ | 'SHOP' /** The Validation metafield owner type. */ - | 'VALIDATION' + | 'VALIDATION'; /** Metafield access permissions for the Storefront API. */ export type MetafieldStorefrontAccess = /** No access. */ | 'NONE' /** Read-only access. */ - | 'PUBLIC_READ' + | 'PUBLIC_READ'; /** * Metaobject access permissions for the Admin API. When the metaobject is app-owned, the owning app always has @@ -218,11 +217,11 @@ export type MetaobjectAdminAccess = /** The merchant and other apps have read-only access. */ | 'PUBLIC_READ' /** The merchant and other apps have read and write access. */ - | 'PUBLIC_READ_WRITE' + | 'PUBLIC_READ_WRITE'; /** Metaobject access permissions for the Storefront API. */ export type MetaobjectStorefrontAccess = /** No access. */ | 'NONE' /** Read-only access. */ - | 'PUBLIC_READ' + | 'PUBLIC_READ'; diff --git a/packages/app/src/cli/api/graphql/app-dev/generated/types.d.ts b/packages/app/src/cli/api/graphql/app-dev/generated/types.d.ts index 024de4d7d71..eb0013d7041 100644 --- a/packages/app/src/cli/api/graphql/app-dev/generated/types.d.ts +++ b/packages/app/src/cli/api/graphql/app-dev/generated/types.d.ts @@ -1,26 +1,25 @@ -/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any, tsdoc/syntax */ +/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any, tsdoc/syntax, @typescript-eslint/no-duplicate-type-constituents, @typescript-eslint/no-redundant-type-constituents, @nx/enforce-module-boundaries */ import {JsonMapType} from '@shopify/cli-kit/node/toml' - -export type Maybe = T | null -export type InputMaybe = Maybe -export type Exact = {[K in keyof T]: T[K]} -export type MakeOptional = Omit & {[SubKey in K]?: Maybe} -export type MakeMaybe = Omit & {[SubKey in K]: Maybe} -export type MakeEmpty = {[_ in K]?: never} -export type Incremental = T | {[P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never} +export type Maybe = T | null; +export type InputMaybe = Maybe; +export type Exact = { [K in keyof T]: T[K] }; +export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; +export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; +export type MakeEmpty = { [_ in K]?: never }; +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { - ID: {input: string; output: string} - String: {input: string; output: string} - Boolean: {input: boolean; output: boolean} - Int: {input: number; output: number} - Float: {input: number; output: number} + ID: { input: string; output: string; } + String: { input: string; output: string; } + Boolean: { input: boolean; output: boolean; } + Int: { input: number; output: number; } + Float: { input: number; output: number; } /** * Represents an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)-encoded date and time string. * For example, 3:50 pm on September 7, 2019 in the time zone of UTC (Coordinated Universal Time) is * represented as `"2019-09-07T15:50:00Z`". */ - DateTime: {input: any; output: any} + DateTime: { input: any; output: any; } /** * A [JSON](https://www.json.org/json-en.html) object. * @@ -36,7 +35,7 @@ export type Scalars = { * } * }` */ - JSON: {input: JsonMapType | string; output: JsonMapType} + JSON: { input: JsonMapType | string; output: JsonMapType; } /** * Represents an [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) and * [RFC 3987](https://datatracker.ietf.org/doc/html/rfc3987)-compliant URI string. @@ -44,5 +43,5 @@ export type Scalars = { * For example, `"https://example.myshopify.com"` is a valid URL. It includes a scheme (`https`) and a host * (`example.myshopify.com`). */ - URL: {input: string; output: string} -} + URL: { input: string; output: string; } +}; diff --git a/packages/app/src/cli/api/graphql/app-management/generated/specifications.ts b/packages/app/src/cli/api/graphql/app-management/generated/specifications.ts index ea44cca51ab..da6721c922d 100644 --- a/packages/app/src/cli/api/graphql/app-management/generated/specifications.ts +++ b/packages/app/src/cli/api/graphql/app-management/generated/specifications.ts @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/no-duplicate-type-constituents */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ import * as Types from './types.js' import {TypedDocumentNode as DocumentNode} from '@graphql-typed-document-node/core' diff --git a/packages/app/src/cli/api/graphql/app-management/generated/types.d.ts b/packages/app/src/cli/api/graphql/app-management/generated/types.d.ts index 91a28421212..75419c09eb1 100644 --- a/packages/app/src/cli/api/graphql/app-management/generated/types.d.ts +++ b/packages/app/src/cli/api/graphql/app-management/generated/types.d.ts @@ -1,26 +1,25 @@ -/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any, tsdoc/syntax */ +/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any, tsdoc/syntax, @typescript-eslint/no-duplicate-type-constituents, @typescript-eslint/no-redundant-type-constituents, @nx/enforce-module-boundaries */ import {JsonMapType} from '@shopify/cli-kit/node/toml' - -export type Maybe = T | null -export type InputMaybe = Maybe -export type Exact = {[K in keyof T]: T[K]} -export type MakeOptional = Omit & {[SubKey in K]?: Maybe} -export type MakeMaybe = Omit & {[SubKey in K]: Maybe} -export type MakeEmpty = {[_ in K]?: never} -export type Incremental = T | {[P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never} +export type Maybe = T | null; +export type InputMaybe = Maybe; +export type Exact = { [K in keyof T]: T[K] }; +export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; +export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; +export type MakeEmpty = { [_ in K]?: never }; +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { - ID: {input: string; output: string} - String: {input: string; output: string} - Boolean: {input: boolean; output: boolean} - Int: {input: number; output: number} - Float: {input: number; output: number} + ID: { input: string; output: string; } + String: { input: string; output: string; } + Boolean: { input: boolean; output: boolean; } + Int: { input: number; output: number; } + Float: { input: number; output: number; } /** * Represents an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)-encoded date and time string. * For example, 3:50 pm on September 7, 2019 in the time zone of UTC (Coordinated Universal Time) is * represented as `"2019-09-07T15:50:00Z`". */ - DateTime: {input: any; output: any} + DateTime: { input: any; output: any; } /** * A [JSON](https://www.json.org/json-en.html) object. * @@ -36,7 +35,7 @@ export type Scalars = { * } * }` */ - JSON: {input: JsonMapType | string; output: JsonMapType} + JSON: { input: JsonMapType | string; output: JsonMapType; } /** * Represents an [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) and * [RFC 3987](https://datatracker.ietf.org/doc/html/rfc3987)-compliant URI string. @@ -44,16 +43,16 @@ export type Scalars = { * For example, `"https://example.myshopify.com"` is a valid URL. It includes a scheme (`https`) and a host * (`example.myshopify.com`). */ - URL: {input: string; output: string} -} + URL: { input: string; output: string; } +}; /** The input fields used to create a new app version. */ export type AppVersionInput = { /** The manifest from which to create the app version. */ - source?: InputMaybe + source?: InputMaybe; /** URL referencing the source from which to create the app version. */ - sourceUrl?: InputMaybe -} + sourceUrl?: InputMaybe; +}; /** Possible error codes that can be returned by AppManagement. */ export type Code = @@ -70,21 +69,21 @@ export type Code = /** A plugin error. */ | 'PLUGIN' /** An unknown error. */ - | 'UNKNOWN' + | 'UNKNOWN'; /** File extension for compressed files used for app sources. */ export type SourceExtension = /** Brotli file extension. */ | 'BR' /** ZIP file extension. */ - | 'ZIP' + | 'ZIP'; /** The input fields for app version metadata. */ export type VersionMetadataInput = { /** Message associated with this app version. */ - message?: InputMaybe + message?: InputMaybe; /** Link to version control, if any. */ - sourceControlUrl?: InputMaybe + sourceControlUrl?: InputMaybe; /** Version tag associated with this app version. */ - versionTag?: InputMaybe -} + versionTag?: InputMaybe; +}; diff --git a/packages/app/src/cli/api/graphql/bulk-operations/generated/bulk-operation-cancel.ts b/packages/app/src/cli/api/graphql/bulk-operations/generated/bulk-operation-cancel.ts index a76f341ced1..d5cd5a967fb 100644 --- a/packages/app/src/cli/api/graphql/bulk-operations/generated/bulk-operation-cancel.ts +++ b/packages/app/src/cli/api/graphql/bulk-operations/generated/bulk-operation-cancel.ts @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/no-redundant-type-constituents */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ import * as Types from './types.js' import {TypedDocumentNode as DocumentNode} from '@graphql-typed-document-node/core' diff --git a/packages/app/src/cli/api/graphql/bulk-operations/generated/bulk-operation-run-mutation.ts b/packages/app/src/cli/api/graphql/bulk-operations/generated/bulk-operation-run-mutation.ts index 7252cc29a5b..55f70a8154a 100644 --- a/packages/app/src/cli/api/graphql/bulk-operations/generated/bulk-operation-run-mutation.ts +++ b/packages/app/src/cli/api/graphql/bulk-operations/generated/bulk-operation-run-mutation.ts @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/no-redundant-type-constituents */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ import * as Types from './types.js' import {TypedDocumentNode as DocumentNode} from '@graphql-typed-document-node/core' diff --git a/packages/app/src/cli/api/graphql/bulk-operations/generated/bulk-operation-run-query.ts b/packages/app/src/cli/api/graphql/bulk-operations/generated/bulk-operation-run-query.ts index c514367800c..5547c46b8a8 100644 --- a/packages/app/src/cli/api/graphql/bulk-operations/generated/bulk-operation-run-query.ts +++ b/packages/app/src/cli/api/graphql/bulk-operations/generated/bulk-operation-run-query.ts @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/no-redundant-type-constituents */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ import * as Types from './types.js' import {TypedDocumentNode as DocumentNode} from '@graphql-typed-document-node/core' diff --git a/packages/app/src/cli/api/graphql/bulk-operations/generated/get-bulk-operation-by-id.ts b/packages/app/src/cli/api/graphql/bulk-operations/generated/get-bulk-operation-by-id.ts index eaa3c34352e..84d1ab97191 100644 --- a/packages/app/src/cli/api/graphql/bulk-operations/generated/get-bulk-operation-by-id.ts +++ b/packages/app/src/cli/api/graphql/bulk-operations/generated/get-bulk-operation-by-id.ts @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/no-redundant-type-constituents */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ import * as Types from './types.js' import {TypedDocumentNode as DocumentNode} from '@graphql-typed-document-node/core' diff --git a/packages/app/src/cli/api/graphql/bulk-operations/generated/list-bulk-operations.ts b/packages/app/src/cli/api/graphql/bulk-operations/generated/list-bulk-operations.ts index d4cd1cef7a1..a8e32522efe 100644 --- a/packages/app/src/cli/api/graphql/bulk-operations/generated/list-bulk-operations.ts +++ b/packages/app/src/cli/api/graphql/bulk-operations/generated/list-bulk-operations.ts @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/no-redundant-type-constituents */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ import * as Types from './types.js' import {TypedDocumentNode as DocumentNode} from '@graphql-typed-document-node/core' diff --git a/packages/app/src/cli/api/graphql/bulk-operations/generated/types.d.ts b/packages/app/src/cli/api/graphql/bulk-operations/generated/types.d.ts index c68fb733477..c8dc91c4962 100644 --- a/packages/app/src/cli/api/graphql/bulk-operations/generated/types.d.ts +++ b/packages/app/src/cli/api/graphql/bulk-operations/generated/types.d.ts @@ -1,53 +1,52 @@ -/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any, tsdoc/syntax */ +/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any, tsdoc/syntax, @typescript-eslint/no-duplicate-type-constituents, @typescript-eslint/no-redundant-type-constituents, @nx/enforce-module-boundaries */ import {JsonMapType} from '@shopify/cli-kit/node/toml' - -export type Maybe = T | null -export type InputMaybe = Maybe -export type Exact = {[K in keyof T]: T[K]} -export type MakeOptional = Omit & {[SubKey in K]?: Maybe} -export type MakeMaybe = Omit & {[SubKey in K]: Maybe} -export type MakeEmpty = {[_ in K]?: never} -export type Incremental = T | {[P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never} +export type Maybe = T | null; +export type InputMaybe = Maybe; +export type Exact = { [K in keyof T]: T[K] }; +export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; +export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; +export type MakeEmpty = { [_ in K]?: never }; +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { - ID: {input: string; output: string} - String: {input: string; output: string} - Boolean: {input: boolean; output: boolean} - Int: {input: number; output: number} - Float: {input: number; output: number} + ID: { input: string; output: string; } + String: { input: string; output: string; } + Boolean: { input: boolean; output: boolean; } + Int: { input: number; output: number; } + Float: { input: number; output: number; } /** * An Amazon Web Services Amazon Resource Name (ARN), including the Region and account ID. * For more information, refer to [Amazon Resource Names](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). */ - ARN: {input: any; output: any} + ARN: { input: any; output: any; } /** * Represents non-fractional signed whole numeric values. Since the value may * exceed the size of a 32-bit integer, it's encoded as a string. */ - BigInt: {input: any; output: any} + BigInt: { input: any; output: any; } /** * A string containing a hexadecimal representation of a color. * * For example, "#6A8D48". */ - Color: {input: any; output: any} + Color: { input: any; output: any; } /** * Represents an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)-encoded date string. * For example, September 7, 2019 is represented as `"2019-07-16"`. */ - Date: {input: any; output: any} + Date: { input: any; output: any; } /** * Represents an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)-encoded date and time string. * For example, 3:50 pm on September 7, 2019 in the time zone of UTC (Coordinated Universal Time) is * represented as `"2019-09-07T15:50:00Z`". */ - DateTime: {input: any; output: any} + DateTime: { input: any; output: any; } /** * A signed decimal number, which supports arbitrary precision and is serialized as a string. * * Example values: `"29.99"`, `"29.999"`. */ - Decimal: {input: any; output: any} + Decimal: { input: any; output: any; } /** * A string containing a strict subset of HTML code. Non-allowed tags will be stripped out. * Allowed tags: @@ -63,14 +62,14 @@ export type Scalars = { * * Example value: `"Your current domain is example.myshopify.com."` */ - FormattedString: {input: any; output: any} + FormattedString: { input: any; output: any; } /** * A string containing HTML code. Refer to the [HTML spec](https://html.spec.whatwg.org/#elements-3) for a * complete list of HTML elements. * * Example value: `"

Grey cotton knit sweater.

"` */ - HTML: {input: any; output: any} + HTML: { input: any; output: any; } /** * A [JSON](https://www.json.org/json-en.html) object. * @@ -86,16 +85,16 @@ export type Scalars = { * } * }` */ - JSON: {input: JsonMapType | string; output: JsonMapType} + JSON: { input: JsonMapType | string; output: JsonMapType; } /** A monetary value string without a currency symbol or code. Example value: `"100.57"`. */ - Money: {input: any; output: any} + Money: { input: any; output: any; } /** * Represents a unique identifier in the Storefront API. A `StorefrontID` value can * be used wherever an ID is expected in the Storefront API. * * Example value: `"Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0LzEwMDc5Nzg1MTAw"`. */ - StorefrontID: {input: any; output: any} + StorefrontID: { input: any; output: any; } /** * Represents an [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) and * [RFC 3987](https://datatracker.ietf.org/doc/html/rfc3987)-compliant URI string. @@ -103,20 +102,20 @@ export type Scalars = { * For example, `"https://example.myshopify.com"` is a valid URL. It includes a scheme (`https`) and a host * (`example.myshopify.com`). */ - URL: {input: string; output: string} + URL: { input: string; output: string; } /** * An unsigned 64-bit integer. Represents whole numeric values between 0 and 2^64 - 1 encoded as a string of base-10 digits. * * Example value: `"50"`. */ - UnsignedInt64: {input: any; output: any} + UnsignedInt64: { input: any; output: any; } /** * Time between UTC time and a location's observed time, in the format `"+HH:MM"` or `"-HH:MM"`. * * Example value: `"-07:00"`. */ - UtcOffset: {input: any; output: any} -} + UtcOffset: { input: any; output: any; } +}; /** Possible error codes that can be returned by `BulkMutationUserError`. */ export type BulkMutationErrorCode = @@ -142,7 +141,7 @@ export type BulkMutationErrorCode = * [Wait for the operation to finish](https://shopify.dev/api/usage/bulk-operations/imports#wait-for-the-operation-to-finish) * before retrying this operation. */ - | 'OPERATION_IN_PROGRESS' + | 'OPERATION_IN_PROGRESS'; /** Error codes for failed bulk operations. */ export type BulkOperationErrorCode = @@ -161,7 +160,7 @@ export type BulkOperationErrorCode = * The operation resulted in partial or incomplete data due to query timeouts during execution. * In some cases, timeouts can be avoided by modifying your `query` to select fewer fields. */ - | 'TIMEOUT' + | 'TIMEOUT'; /** The valid values for the status of a bulk operation. */ export type BulkOperationStatus = @@ -184,14 +183,14 @@ export type BulkOperationStatus = */ | 'FAILED' /** The bulk operation is runnning. */ - | 'RUNNING' + | 'RUNNING'; /** The valid values for the bulk operation's type. */ export type BulkOperationType = /** The bulk operation is a mutation. */ | 'MUTATION' /** The bulk operation is a query. */ - | 'QUERY' + | 'QUERY'; /** Possible error codes that can be returned by `BulkOperationUserError`. */ export type BulkOperationUserErrorCode = @@ -200,14 +199,14 @@ export type BulkOperationUserErrorCode = /** Bulk operations limit reached. Please try again later. */ | 'LIMIT_REACHED' /** A bulk operation is already in progress. */ - | 'OPERATION_IN_PROGRESS' + | 'OPERATION_IN_PROGRESS'; /** The set of valid sort keys for the BulkOperations query. */ export type BulkOperationsSortKeys = /** Sort by the `completed_at` value. */ | 'COMPLETED_AT' /** Sort by the `created_at` value. */ - | 'CREATED_AT' + | 'CREATED_AT'; /** * The possible HTTP methods that can be used when sending a request to upload a file using information from a @@ -217,7 +216,7 @@ export type StagedUploadHttpMethodType = /** The POST HTTP method. */ | 'POST' /** The PUT HTTP method. */ - | 'PUT' + | 'PUT'; /** The input fields for generating staged upload targets. */ export type StagedUploadInput = { @@ -226,19 +225,19 @@ export type StagedUploadInput = { * [VIDEO](https://shopify.dev/api/admin-graphql/latest/enums/StagedUploadTargetGenerateUploadResource#value-video) * or [MODEL_3D](https://shopify.dev/api/admin-graphql/latest/enums/StagedUploadTargetGenerateUploadResource#value-model3d). */ - fileSize?: InputMaybe + fileSize?: InputMaybe; /** The file's name and extension. */ - filename: Scalars['String']['input'] + filename: Scalars['String']['input']; /** * The HTTP method to be used when sending a request to upload the file using the returned staged * upload target. */ - httpMethod?: InputMaybe + httpMethod?: InputMaybe; /** The file's MIME type. */ - mimeType: Scalars['String']['input'] + mimeType: Scalars['String']['input']; /** The file's intended Shopify resource type. */ - resource: StagedUploadTargetGenerateUploadResource -} + resource: StagedUploadTargetGenerateUploadResource; +}; /** The resource type to receive. */ export type StagedUploadTargetGenerateUploadResource = @@ -327,4 +326,4 @@ export type StagedUploadTargetGenerateUploadResource = * or to the [Files page](https://shopify.com/admin/settings/files) in Shopify admin using the * [fileCreate mutation](https://shopify.dev/api/admin-graphql/latest/mutations/fileCreate). */ - | 'VIDEO' + | 'VIDEO'; diff --git a/packages/app/src/cli/api/graphql/business-platform-destinations/generated/types.d.ts b/packages/app/src/cli/api/graphql/business-platform-destinations/generated/types.d.ts index e37c29d4e3f..9fed0e6e078 100644 --- a/packages/app/src/cli/api/graphql/business-platform-destinations/generated/types.d.ts +++ b/packages/app/src/cli/api/graphql/business-platform-destinations/generated/types.d.ts @@ -1,23 +1,24 @@ -/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any */ -export type Maybe = T | null -export type InputMaybe = Maybe -export type Exact = {[K in keyof T]: T[K]} -export type MakeOptional = Omit & {[SubKey in K]?: Maybe} -export type MakeMaybe = Omit & {[SubKey in K]: Maybe} -export type MakeEmpty = {[_ in K]?: never} -export type Incremental = T | {[P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never} +/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any, tsdoc/syntax, @typescript-eslint/no-duplicate-type-constituents, @typescript-eslint/no-redundant-type-constituents, @nx/enforce-module-boundaries */ +import {JsonMapType} from '@shopify/cli-kit/node/toml' +export type Maybe = T | null; +export type InputMaybe = Maybe; +export type Exact = { [K in keyof T]: T[K] }; +export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; +export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; +export type MakeEmpty = { [_ in K]?: never }; +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { - ID: {input: string; output: string} - String: {input: string; output: string} - Boolean: {input: boolean; output: boolean} - Int: {input: number; output: number} - Float: {input: number; output: number} - DestinationID: {input: any; output: any} - DestinationPublicID: {input: any; output: any} - GlobalID: {input: string; output: string} + ID: { input: string; output: string; } + String: { input: string; output: string; } + Boolean: { input: boolean; output: boolean; } + Int: { input: number; output: number; } + Float: { input: number; output: number; } + DestinationID: { input: any; output: any; } + DestinationPublicID: { input: any; output: any; } + GlobalID: { input: string; output: string; } /** An ISO 8601-encoded datetime */ - ISO8601DateTime: {input: any; output: any} + ISO8601DateTime: { input: any; output: any; } /** The ID for a Organization. */ - OrganizationID: {input: any; output: any} -} + OrganizationID: { input: any; output: any; } +}; diff --git a/packages/app/src/cli/api/graphql/business-platform-organizations/generated/fetch_store_by_domain.ts b/packages/app/src/cli/api/graphql/business-platform-organizations/generated/fetch_store_by_domain.ts index 9b899f0ee52..8b3c8c66da8 100644 --- a/packages/app/src/cli/api/graphql/business-platform-organizations/generated/fetch_store_by_domain.ts +++ b/packages/app/src/cli/api/graphql/business-platform-organizations/generated/fetch_store_by_domain.ts @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/no-duplicate-type-constituents */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ import * as Types from './types.js' import {TypedDocumentNode as DocumentNode} from '@graphql-typed-document-node/core' diff --git a/packages/app/src/cli/api/graphql/business-platform-organizations/generated/list_app_dev_stores.ts b/packages/app/src/cli/api/graphql/business-platform-organizations/generated/list_app_dev_stores.ts index 5dd861a7c1a..aa76f2a7f06 100644 --- a/packages/app/src/cli/api/graphql/business-platform-organizations/generated/list_app_dev_stores.ts +++ b/packages/app/src/cli/api/graphql/business-platform-organizations/generated/list_app_dev_stores.ts @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/no-duplicate-type-constituents */ +/* eslint-disable @typescript-eslint/consistent-type-definitions */ import * as Types from './types.js' import {TypedDocumentNode as DocumentNode} from '@graphql-typed-document-node/core' diff --git a/packages/app/src/cli/api/graphql/business-platform-organizations/generated/types.d.ts b/packages/app/src/cli/api/graphql/business-platform-organizations/generated/types.d.ts index 48f87ac5f97..688d4605f48 100644 --- a/packages/app/src/cli/api/graphql/business-platform-organizations/generated/types.d.ts +++ b/packages/app/src/cli/api/graphql/business-platform-organizations/generated/types.d.ts @@ -1,87 +1,91 @@ -/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any, tsdoc/syntax, @typescript-eslint/no-duplicate-type-constituents, @typescript-eslint/no-redundant-type-constituents, @nx/enforce-module-boundaries */ import {JsonMapType} from '@shopify/cli-kit/node/toml' - -export type Maybe = T | null -export type InputMaybe = Maybe -export type Exact = {[K in keyof T]: T[K]} -export type MakeOptional = Omit & {[SubKey in K]?: Maybe} -export type MakeMaybe = Omit & {[SubKey in K]: Maybe} -export type MakeEmpty = {[_ in K]?: never} -export type Incremental = T | {[P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never} +export type Maybe = T | null; +export type InputMaybe = Maybe; +export type Exact = { [K in keyof T]: T[K] }; +export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; +export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; +export type MakeEmpty = { [_ in K]?: never }; +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { - ID: {input: string; output: string} - String: {input: string; output: string} - Boolean: {input: boolean; output: boolean} - Int: {input: number; output: number} - Float: {input: number; output: number} - AccessRoleAssignee: {input: any; output: any} + ID: { input: string; output: string; } + String: { input: string; output: string; } + Boolean: { input: boolean; output: boolean; } + Int: { input: number; output: number; } + Float: { input: number; output: number; } + AccessRoleAssignee: { input: any; output: any; } /** The ID for a AccessRole. */ - AccessRoleID: {input: any; output: any} - AccessRoleRecordId: {input: any; output: any} + AccessRoleID: { input: any; output: any; } + AccessRoleRecordId: { input: any; output: any; } /** The ID for a ActionAudit. */ - ActionAuditID: {input: any; output: any} + ActionAuditID: { input: any; output: any; } /** The ID for a Address. */ - AddressID: {input: any; output: any} + AddressID: { input: any; output: any; } /** The ID for a BulkDataOperation. */ - BulkDataOperationID: {input: any; output: any} + BulkDataOperationID: { input: any; output: any; } /** The ID for a BusinessUser. */ - BusinessUserID: {input: any; output: any} + BusinessUserID: { input: any; output: any; } /** A signed decimal number, which supports arbitrary precision and is serialized as a string. */ - Decimal: {input: any; output: any} + Decimal: { input: any; output: any; } /** The ID for a DocumentAttachment. */ - DocumentAttachmentID: {input: any; output: any} + DocumentAttachmentID: { input: any; output: any; } /** The ID for a EntitySupportingDocument. */ - EntitySupportingDocumentID: {input: any; output: any} - GlobalID: {input: string; output: string} + EntitySupportingDocumentID: { input: any; output: any; } + GlobalID: { input: string; output: string; } /** The ID for a GovernmentIdentifier. */ - GovernmentIdentifierID: {input: any; output: any} + GovernmentIdentifierID: { input: any; output: any; } /** The ID for a Group. */ - GroupID: {input: any; output: any} + GroupID: { input: any; output: any; } /** An ISO 8601-encoded date */ - ISO8601Date: {input: any; output: any} + ISO8601Date: { input: any; output: any; } /** An ISO 8601-encoded datetime */ - ISO8601DateTime: {input: any; output: any} + ISO8601DateTime: { input: any; output: any; } /** Represents untyped JSON */ - JSON: {input: JsonMapType | string; output: JsonMapType} + JSON: { input: JsonMapType | string; output: JsonMapType; } /** The ID for a LegalEntity. */ - LegalEntityID: {input: any; output: any} + LegalEntityID: { input: any; output: any; } /** The ID for a OrganizationDomain. */ - OrganizationDomainID: {input: any; output: any} + OrganizationDomainID: { input: any; output: any; } /** The ID for a Organization. */ - OrganizationID: {input: any; output: any} + OrganizationID: { input: any; output: any; } /** The ID for a OrganizationUser. */ - OrganizationUserID: {input: any; output: any} + OrganizationUserID: { input: any; output: any; } /** The ID for a PersonAlias. */ - PersonAliasID: {input: any; output: any} + PersonAliasID: { input: any; output: any; } /** The ID for a Person. */ - PersonID: {input: any; output: any} + PersonID: { input: any; output: any; } /** The ID for a Principal. */ - PrincipalID: {input: any; output: any} + PrincipalID: { input: any; output: any; } /** The ID for a Property. */ - PropertyID: {input: any; output: any} - PropertyId: {input: string; output: string} - PropertyPublicID: {input: string; output: string} + PropertyID: { input: any; output: any; } + PropertyId: { input: string; output: string; } + PropertyPublicID: { input: string; output: string; } /** The ID for a PropertyTransferRequest. */ - PropertyTransferRequestID: {input: any; output: any} + PropertyTransferRequestID: { input: any; output: any; } /** The ID for a Role. */ - RoleID: {input: any; output: any} + RoleID: { input: any; output: any; } /** The ID for a Shop. */ - ShopID: {input: any; output: any} + ShopID: { input: any; output: any; } /** The ID for a ShopifyShop. */ - ShopifyShopID: {input: any; output: any} + ShopifyShopID: { input: any; output: any; } /** The ID for a StoreAdditionRequest. */ - StoreAdditionRequestID: {input: any; output: any} - SupportedEntityId: {input: any; output: any} + StoreAdditionRequestID: { input: any; output: any; } + SupportedEntityId: { input: any; output: any; } /** The ID for a SupportingDocument. */ - SupportingDocumentID: {input: any; output: any} + SupportingDocumentID: { input: any; output: any; } /** An RFC 3986 and RFC 3987 compliant URI string. */ - URL: {input: string; output: string} -} + URL: { input: string; output: string; } +}; export type OrganizationUserProvisionShopAccessInput = { /** The shop to provision the requester on. */ - shopifyShopId: Scalars['PropertyPublicID']['input'] -} + shopifyShopId: Scalars['PropertyPublicID']['input']; +}; -export type Store = 'APP_DEVELOPMENT' | 'CLIENT_TRANSFER' | 'DEVELOPMENT' | 'DEVELOPMENT_SUPERSET' | 'PRODUCTION' +export type Store = + | 'APP_DEVELOPMENT' + | 'CLIENT_TRANSFER' + | 'DEVELOPMENT' + | 'DEVELOPMENT_SUPERSET' + | 'PRODUCTION'; diff --git a/packages/app/src/cli/api/graphql/functions/generated/types.d.ts b/packages/app/src/cli/api/graphql/functions/generated/types.d.ts index 2d85fa63eea..dad1fa048e1 100644 --- a/packages/app/src/cli/api/graphql/functions/generated/types.d.ts +++ b/packages/app/src/cli/api/graphql/functions/generated/types.d.ts @@ -1,18 +1,19 @@ -/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention */ -export type Maybe = T | null -export type InputMaybe = Maybe -export type Exact = {[K in keyof T]: T[K]} -export type MakeOptional = Omit & {[SubKey in K]?: Maybe} -export type MakeMaybe = Omit & {[SubKey in K]: Maybe} -export type MakeEmpty = {[_ in K]?: never} -export type Incremental = T | {[P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never} +/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any, tsdoc/syntax, @typescript-eslint/no-duplicate-type-constituents, @typescript-eslint/no-redundant-type-constituents, @nx/enforce-module-boundaries */ +import {JsonMapType} from '@shopify/cli-kit/node/toml' +export type Maybe = T | null; +export type InputMaybe = Maybe; +export type Exact = { [K in keyof T]: T[K] }; +export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; +export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; +export type MakeEmpty = { [_ in K]?: never }; +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { - ID: {input: string; output: string} - String: {input: string; output: string} - Boolean: {input: boolean; output: boolean} - Int: {input: number; output: number} - Float: {input: number; output: number} + ID: { input: string; output: string; } + String: { input: string; output: string; } + Boolean: { input: boolean; output: boolean; } + Int: { input: number; output: number; } + Float: { input: number; output: number; } /** * Represents an [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) and * [RFC 3987](https://datatracker.ietf.org/doc/html/rfc3987)-compliant URI string. @@ -20,5 +21,5 @@ export type Scalars = { * For example, `"https://example.myshopify.com"` is a valid URL. It includes a scheme (`https`) and a host * (`example.myshopify.com`). */ - URL: {input: string; output: string} -} + URL: { input: string; output: string; } +}; diff --git a/packages/app/src/cli/api/graphql/partners/generated/types.d.ts b/packages/app/src/cli/api/graphql/partners/generated/types.d.ts index b9572774e7a..1ffd775f795 100644 --- a/packages/app/src/cli/api/graphql/partners/generated/types.d.ts +++ b/packages/app/src/cli/api/graphql/partners/generated/types.d.ts @@ -1,34 +1,33 @@ -/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any, tsdoc/syntax, @typescript-eslint/no-duplicate-type-constituents, @typescript-eslint/no-redundant-type-constituents, @nx/enforce-module-boundaries */ import {JsonMapType} from '@shopify/cli-kit/node/toml' - -export type Maybe = T | null -export type InputMaybe = Maybe -export type Exact = {[K in keyof T]: T[K]} -export type MakeOptional = Omit & {[SubKey in K]?: Maybe} -export type MakeMaybe = Omit & {[SubKey in K]: Maybe} -export type MakeEmpty = {[_ in K]?: never} -export type Incremental = T | {[P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never} +export type Maybe = T | null; +export type InputMaybe = Maybe; +export type Exact = { [K in keyof T]: T[K] }; +export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; +export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; +export type MakeEmpty = { [_ in K]?: never }; +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { - ID: {input: string; output: string} - String: {input: string; output: string} - Boolean: {input: boolean; output: boolean} - Int: {input: number; output: number} - Float: {input: number; output: number} + ID: { input: string; output: string; } + String: { input: string; output: string; } + Boolean: { input: boolean; output: boolean; } + Int: { input: number; output: number; } + Float: { input: number; output: number; } /** * An [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) encoded UTC date time * string. Example value: `"2019-07-03T20:47:55.123456Z"`. */ - DateTime: {input: any; output: any} + DateTime: { input: any; output: any; } /** * Deprecated: Supported extension types. * This used to include a list of extension types, we mantain it to keep compatibility with the old schema */ - ExtensionType: {input: any; output: any} + ExtensionType: { input: any; output: any; } /** Represents untyped JSON */ - JSON: {input: JsonMapType | string; output: JsonMapType} + JSON: { input: JsonMapType | string; output: JsonMapType; } /** A valid URL, transported as a string. */ - Url: {input: any; output: any} + Url: { input: any; output: any; } /** A valid webhook subscription endpoint string. */ - WebhookSubscriptionEndpoint: {input: any; output: any} -} + WebhookSubscriptionEndpoint: { input: any; output: any; } +}; diff --git a/packages/app/src/cli/api/graphql/webhooks/generated/types.d.ts b/packages/app/src/cli/api/graphql/webhooks/generated/types.d.ts index 2b9d2b25a6f..f0d3fccb134 100644 --- a/packages/app/src/cli/api/graphql/webhooks/generated/types.d.ts +++ b/packages/app/src/cli/api/graphql/webhooks/generated/types.d.ts @@ -1,16 +1,17 @@ -/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention */ -export type Maybe = T | null -export type InputMaybe = Maybe -export type Exact = {[K in keyof T]: T[K]} -export type MakeOptional = Omit & {[SubKey in K]?: Maybe} -export type MakeMaybe = Omit & {[SubKey in K]: Maybe} -export type MakeEmpty = {[_ in K]?: never} -export type Incremental = T | {[P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never} +/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any, tsdoc/syntax, @typescript-eslint/no-duplicate-type-constituents, @typescript-eslint/no-redundant-type-constituents, @nx/enforce-module-boundaries */ +import {JsonMapType} from '@shopify/cli-kit/node/toml' +export type Maybe = T | null; +export type InputMaybe = Maybe; +export type Exact = { [K in keyof T]: T[K] }; +export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; +export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; +export type MakeEmpty = { [_ in K]?: never }; +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { - ID: {input: string; output: string} - String: {input: string; output: string} - Boolean: {input: boolean; output: boolean} - Int: {input: number; output: number} - Float: {input: number; output: number} -} + ID: { input: string; output: string; } + String: { input: string; output: string; } + Boolean: { input: boolean; output: boolean; } + Int: { input: number; output: number; } + Float: { input: number; output: number; } +}; diff --git a/packages/app/src/cli/models/app/app.ts b/packages/app/src/cli/models/app/app.ts index ead77d10470..9166f25b206 100644 --- a/packages/app/src/cli/models/app/app.ts +++ b/packages/app/src/cli/models/app/app.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ import {AppErrors, isWebType} from './loader.js' import {ensurePathStartsWithSlash} from './validation/common.js' import {Identifiers} from './identifiers.js' @@ -374,8 +373,7 @@ type AppConstructor< export class App< TConfig extends AppConfiguration = AppConfiguration, TModuleSpec extends ExtensionSpecification = ExtensionSpecification, -> implements AppInterface -{ +> implements AppInterface { name: string idEnvironmentVariableName: 'SHOPIFY_API_KEY' = 'SHOPIFY_API_KEY' as const directory: string diff --git a/packages/app/src/cli/models/app/identifiers.ts b/packages/app/src/cli/models/app/identifiers.ts index 93f6039d6d4..387ec010084 100644 --- a/packages/app/src/cli/models/app/identifiers.ts +++ b/packages/app/src/cli/models/app/identifiers.ts @@ -65,7 +65,6 @@ export async function updateAppIdentifiers( Object.keys(identifiers.extensions).forEach((identifier) => { const envVariable = `SHOPIFY_${constantize(identifier)}_ID` if (!systemEnvironment[envVariable]) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion updatedVariables[envVariable] = identifiers.extensions[identifier]! } }) @@ -110,7 +109,6 @@ export function getAppIdentifiers( const extensionsIdentifiers: {[key: string]: string} = {} const processExtension = (extension: ExtensionInstance) => { if (Object.keys(envVariables).includes(extension.idEnvironmentVariableName)) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion extensionsIdentifiers[extension.localIdentifier] = envVariables[extension.idEnvironmentVariableName]! } } diff --git a/packages/app/src/cli/models/app/loader.ts b/packages/app/src/cli/models/app/loader.ts index d83e575846c..9e7172feb65 100644 --- a/packages/app/src/cli/models/app/loader.ts +++ b/packages/app/src/cli/models/app/loader.ts @@ -532,7 +532,7 @@ class AppLoader 1) { const conflictingPaths = websOfType.map((web) => joinPath(web.directory, configurationFileNames.web)) const pathsList = conflictingPaths.map((path) => ` ${path}`).join('\n') - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const lastConflictingPath = conflictingPaths[conflictingPaths.length - 1]! this.abortOrReport( outputContent`You can only have one "web" configuration file with the ${outputToken.yellow( @@ -1286,7 +1286,6 @@ async function logMetadataForLoadedAppUsingRawValues( if (extensionsBreakdownMapping[extension.type] === undefined) { extensionsBreakdownMapping[extension.type] = 1 } else { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion extensionsBreakdownMapping[extension.type]!++ } } diff --git a/packages/app/src/cli/models/extensions/extension-instance.test.ts b/packages/app/src/cli/models/extensions/extension-instance.test.ts index 2adc27a7d1b..5a808958df9 100644 --- a/packages/app/src/cli/models/extensions/extension-instance.test.ts +++ b/packages/app/src/cli/models/extensions/extension-instance.test.ts @@ -1,5 +1,6 @@ import {SingleWebhookSubscriptionType} from './specifications/app_config_webhook_schemas/webhooks_schema.js' import {MAX_EXTENSION_HANDLE_LENGTH} from './schemas.js' +import {FunctionConfigType} from './specifications/function.js' import { testApp, testAppConfigExtensions, @@ -13,7 +14,6 @@ import { testSingleWebhookSubscriptionExtension, placeholderAppConfiguration, } from '../app/app.test-data.js' -import {FunctionConfigType} from '../extensions/specifications/function.js' import {ExtensionBuildOptions, buildUIExtension} from '../../services/build/extension.js' import {DeveloperPlatformClient} from '../../utilities/developer-platform-client.js' import {joinPath} from '@shopify/cli-kit/node/path' diff --git a/packages/app/src/cli/models/extensions/extension-instance.ts b/packages/app/src/cli/models/extensions/extension-instance.ts index 3a37dd9aaf8..2634ce3d972 100644 --- a/packages/app/src/cli/models/extensions/extension-instance.ts +++ b/packages/app/src/cli/models/extensions/extension-instance.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ - import {BaseConfigType, MAX_EXTENSION_HANDLE_LENGTH, MAX_UID_LENGTH} from './schemas.js' import {FunctionConfigType} from './specifications/function.js' import {ExtensionFeature, ExtensionSpecification} from './specification.js' diff --git a/packages/app/src/cli/models/extensions/specification.ts b/packages/app/src/cli/models/extensions/specification.ts index d40a17dd115..ff794e743f3 100644 --- a/packages/app/src/cli/models/extensions/specification.ts +++ b/packages/app/src/cli/models/extensions/specification.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ import {ZodSchemaType, BaseConfigType, BaseSchema} from './schemas.js' import {ExtensionInstance} from './extension-instance.js' import {blocks} from '../../constants.js' @@ -159,8 +158,9 @@ type ForbiddenFields = /** * Partial ExtensionSpec type used when creating a new ExtensionSpec, the only mandatory field is the identifier */ -interface CreateExtensionSpecType - extends Partial, ForbiddenFields>> { +interface CreateExtensionSpecType extends Partial< + Omit, ForbiddenFields> +> { identifier: string appModuleFeatures: (config?: TConfiguration) => ExtensionFeature[] schema?: ZodSchemaType @@ -378,7 +378,7 @@ function defaultAppConfigReverseTransform(schema: zod.ZodType, c result[key] = defaultAppConfigReverseTransform(innerSchema, content) } else { if (content[key] !== undefined) result[key] = content[key] - // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete content[key] } return result diff --git a/packages/app/src/cli/models/extensions/specifications/theme.ts b/packages/app/src/cli/models/extensions/specifications/theme.ts index 6debcc8135e..b3cc7510d27 100644 --- a/packages/app/src/cli/models/extensions/specifications/theme.ts +++ b/packages/app/src/cli/models/extensions/specifications/theme.ts @@ -109,7 +109,7 @@ function validateFile(filepath: string, dirname: string): void { `Make sure all theme app extension files are in the supported directories: ${SUPPORTED_BUCKETS.join(', ')}`, ) } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const filenameValidation = SUPPORTED_EXTS[dirname]! if (!filepath.match(filenameValidation.validator)) { throw new AbortError(`Invalid filename in your theme app extension: ${filepath} diff --git a/packages/app/src/cli/models/extensions/specifications/transform/app_config_webhook.ts b/packages/app/src/cli/models/extensions/specifications/transform/app_config_webhook.ts index 22480d02c2d..45a4b6ba079 100644 --- a/packages/app/src/cli/models/extensions/specifications/transform/app_config_webhook.ts +++ b/packages/app/src/cli/models/extensions/specifications/transform/app_config_webhook.ts @@ -81,7 +81,7 @@ export function reduceWebhooks( const existingSubscription = findSubscription(accumulator, subscription) if (existingSubscription) { if (property && subscription?.[property]?.length) { - // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion existingSubscription[property]?.push(...subscription[property]!) } else { if (subscription.topics) { diff --git a/packages/app/src/cli/prompts/config.ts b/packages/app/src/cli/prompts/config.ts index a93eaff4d15..4edced86db5 100644 --- a/packages/app/src/cli/prompts/config.ts +++ b/packages/app/src/cli/prompts/config.ts @@ -50,7 +50,7 @@ export async function selectConfigFile(directory: string): Promise basename(path)) if (files.length === 0) return err('Could not find any shopify.app.toml file in the directory.') - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + if (files.length === 1) return ok(files[0]!) const chosen = await renderSelectPrompt({ diff --git a/packages/app/src/cli/prompts/dev.ts b/packages/app/src/cli/prompts/dev.ts index 71cc296a88e..ab16c8612e9 100644 --- a/packages/app/src/cli/prompts/dev.ts +++ b/packages/app/src/cli/prompts/dev.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ import {Organization, MinimalOrganizationApp, OrganizationStore, MinimalAppIdentifiers} from '../models/organization.js' import {getTomls} from '../utilities/app/config/getTomls.js' import {setCachedCommandTomlMap} from '../services/local-storage.js' diff --git a/packages/app/src/cli/prompts/generate/extension.ts b/packages/app/src/cli/prompts/generate/extension.ts index a4d0e63a03a..425d7cf5705 100644 --- a/packages/app/src/cli/prompts/generate/extension.ts +++ b/packages/app/src/cli/prompts/generate/extension.ts @@ -90,7 +90,6 @@ const generateExtensionPrompts = async ( }) } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const extensionTemplate = extensionTemplates.find((template) => template.identifier === templateType)! const name = options.name || (await promptName(options.directory, extensionTemplate.defaultName)) diff --git a/packages/app/src/cli/services/app-context.test.ts b/packages/app/src/cli/services/app-context.test.ts index 37ffaf956cc..6e00b385f30 100644 --- a/packages/app/src/cli/services/app-context.test.ts +++ b/packages/app/src/cli/services/app-context.test.ts @@ -424,7 +424,7 @@ describe('localAppContext', () => { }, errors: undefined, }), - validate: async () => ({isErr: () => false, isOk: () => true} as any), + validate: async () => ({isErr: () => false, isOk: () => true}) as any, contributeToAppConfigurationSchema: (schema: any) => schema, } as any, ]) diff --git a/packages/app/src/cli/services/app-logs/sources.ts b/packages/app/src/cli/services/app-logs/sources.ts index 4c38d538d17..7eb85f64540 100644 --- a/packages/app/src/cli/services/app-logs/sources.ts +++ b/packages/app/src/cli/services/app-logs/sources.ts @@ -1,5 +1,5 @@ +import {sourcesForApp} from './utils.js' import {AppInterface} from '../../models/app/app.js' -import {sourcesForApp} from '../../services/app-logs/utils.js' import {formatSection, outputResult} from '@shopify/cli-kit/node/output' export function sources(app: AppInterface) { @@ -9,14 +9,12 @@ export function sources(app: AppInterface) { const tokens = source.split('.') if (tokens.length >= 2) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const sourceNamespace = tokens[0]! if (!sourcesByNamespace.has(sourceNamespace)) { sourcesByNamespace.set(sourceNamespace, []) } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion sourcesByNamespace.set(sourceNamespace, [...sourcesByNamespace.get(sourceNamespace)!, source]) } }) diff --git a/packages/app/src/cli/services/build/extension.ts b/packages/app/src/cli/services/build/extension.ts index 0e992326a25..bb8b5b7fe03 100644 --- a/packages/app/src/cli/services/build/extension.ts +++ b/packages/app/src/cli/services/build/extension.ts @@ -229,7 +229,7 @@ async function buildOtherFunction(extension: ExtensionInstance, options: BuildFu async function runCommand(buildCommand: string, extension: ExtensionInstance, options: BuildFunctionExtensionOptions) { const buildCommandComponents = buildCommand.split(' ') options.stdout.write(`Building function ${extension.localIdentifier}...`) - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + await exec(buildCommandComponents[0]!, buildCommandComponents.slice(1), { stdout: options.stdout, stderr: options.stderr, diff --git a/packages/app/src/cli/services/context/breakdown-extensions.ts b/packages/app/src/cli/services/context/breakdown-extensions.ts index e685a07cd8c..283281b46e0 100644 --- a/packages/app/src/cli/services/context/breakdown-extensions.ts +++ b/packages/app/src/cli/services/context/breakdown-extensions.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ import {ensureExtensionsIds} from './identifiers-extensions.js' import {EnsureDeploymentIdsPresenceOptions, LocalSource, RemoteSource} from './identifiers.js' import {versionDiffByVersion} from '../release/version-diff.js' diff --git a/packages/app/src/cli/services/context/prompts.ts b/packages/app/src/cli/services/context/prompts.ts index afc88a99fea..c447b257fda 100644 --- a/packages/app/src/cli/services/context/prompts.ts +++ b/packages/app/src/cli/services/context/prompts.ts @@ -27,7 +27,7 @@ export async function selectRemoteSourcePrompt( message: `How would you like to deploy your "${localSource.handle}"?`, choices: remoteOptions, }) - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return remoteSourcesOfSameType.find((remote) => remote.uuid === uuid)! } diff --git a/packages/app/src/cli/services/deploy.test.ts b/packages/app/src/cli/services/deploy.test.ts index 63bc04b3ff0..3718bc092b6 100644 --- a/packages/app/src/cli/services/deploy.test.ts +++ b/packages/app/src/cli/services/deploy.test.ts @@ -1122,9 +1122,8 @@ describe('ImportExtensionsIfNeeded', () => { } as any), }) - const identifiersModule = await vi.importActual( - './context/identifiers.js', - ) + const identifiersModule = + await vi.importActual('./context/identifiers.js') // When/Then await expect( diff --git a/packages/app/src/cli/services/dev.ts b/packages/app/src/cli/services/dev.ts index af0af066266..b4de346b615 100644 --- a/packages/app/src/cli/services/dev.ts +++ b/packages/app/src/cli/services/dev.ts @@ -500,7 +500,6 @@ async function validateCustomPorts(webConfigs: Web[], graphiqlPort: number) { } await Promise.all([ ...allPorts.map(async (port) => { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const portAvailable = await checkPortAvailability(port!) if (!portAvailable) { throw new AbortError(`Hard-coded port ${port} is not available, please choose a different one.`) diff --git a/packages/app/src/cli/services/dev/extension/server/utilities.ts b/packages/app/src/cli/services/dev/extension/server/utilities.ts index 0c2ce1a6454..c71fc44a7b8 100644 --- a/packages/app/src/cli/services/dev/extension/server/utilities.ts +++ b/packages/app/src/cli/services/dev/extension/server/utilities.ts @@ -34,14 +34,14 @@ export function getExtensionPointRedirectUrl( case 'checkout': // This can never be null because we always generate it // whenever there is an extension point targeting Checkout - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + rawUrl.pathname = options.checkoutCartUrl! rawUrl.searchParams.append('dev', `${options.url}/extensions`) break case 'post_purchase': // This can never be null because we always generate it // whenever there is an extension point targeting Post Purchase - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + rawUrl.pathname = options.checkoutCartUrl! rawUrl.searchParams.set( diff --git a/packages/app/src/cli/services/dev/extension/websocket/handlers.ts b/packages/app/src/cli/services/dev/extension/websocket/handlers.ts index 6253bff394f..cb6d73f3950 100644 --- a/packages/app/src/cli/services/dev/extension/websocket/handlers.ts +++ b/packages/app/src/cli/services/dev/extension/websocket/handlers.ts @@ -98,7 +98,6 @@ export function handleLogEvent(eventData: LogPayload, options: SetupWebSocketCon export function getOnMessageHandler(wss: WebSocketServer, options: SetupWebSocketConnectionOptions) { return (data: RawData) => { - // eslint-disable-next-line @typescript-eslint/no-base-to-string const jsonData = JSON.parse(data.toString()) const {event: eventType, data: eventData} = jsonData diff --git a/packages/app/src/cli/services/dev/graphiql/server.ts b/packages/app/src/cli/services/dev/graphiql/server.ts index 266d62c8347..078ef111736 100644 --- a/packages/app/src/cli/services/dev/graphiql/server.ts +++ b/packages/app/src/cli/services/dev/graphiql/server.ts @@ -145,7 +145,6 @@ export function setupGraphiQLServer({ throw err } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const apiVersion = apiVersions.sort().reverse()[0]! function decodeQueryString(input: string | undefined) { diff --git a/packages/app/src/cli/services/dev/processes/setup-dev-processes.ts b/packages/app/src/cli/services/dev/processes/setup-dev-processes.ts index 0687de5a444..da6741c4bbe 100644 --- a/packages/app/src/cli/services/dev/processes/setup-dev-processes.ts +++ b/packages/app/src/cli/services/dev/processes/setup-dev-processes.ts @@ -26,12 +26,11 @@ import {firstPartyDev} from '@shopify/cli-kit/node/context/local' import {getEnvironmentVariables} from '@shopify/cli-kit/node/environment' import {outputInfo} from '@shopify/cli-kit/node/output' -interface ProxyServerProcess - extends BaseProcess<{ - port: number - rules: {[key: string]: string} - localhostCert?: LocalhostCert - }> { +interface ProxyServerProcess extends BaseProcess<{ + port: number + rules: {[key: string]: string} + localhostCert?: LocalhostCert +}> { type: 'proxy-server' } diff --git a/packages/app/src/cli/services/dev/processes/theme-app-extension.ts b/packages/app/src/cli/services/dev/processes/theme-app-extension.ts index 6a032815e03..37b6f3c8c8d 100644 --- a/packages/app/src/cli/services/dev/processes/theme-app-extension.ts +++ b/packages/app/src/cli/services/dev/processes/theme-app-extension.ts @@ -42,7 +42,6 @@ export async function setupPreviewThemeAppExtensionsProcess( return } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const themeExtension = themeExtensions[0]! const themeExtensionDirectory = themeExtension.directory const themeExtensionPort = options.themeExtensionPort ?? 9293 diff --git a/packages/app/src/cli/services/dev/processes/web.ts b/packages/app/src/cli/services/dev/processes/web.ts index ceb16ebc69a..f5d2b4601df 100644 --- a/packages/app/src/cli/services/dev/processes/web.ts +++ b/packages/app/src/cli/services/dev/processes/web.ts @@ -58,7 +58,7 @@ export async function setupWebProcesses({ hmrServerPort && web.configuration.roles.includes(WebType.Frontend) ? { port: hmrServerPort, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + httpPaths: web.configuration.hmr_server!.http_paths, } : undefined @@ -183,7 +183,7 @@ async function runCommands({ for (const command of commands) { const [cmd, ...args] = command.split(' ') if (cmd?.length === 0) continue - // eslint-disable-next-line no-await-in-loop, @typescript-eslint/no-non-null-assertion + // eslint-disable-next-line no-await-in-loop await exec(cmd!, args, { cwd: directory, stdout: showOutput ? stdout : undefined, diff --git a/packages/app/src/cli/services/dev/select-store.ts b/packages/app/src/cli/services/dev/select-store.ts index 6e8d19f4d66..d02c8969ee0 100644 --- a/packages/app/src/cli/services/dev/select-store.ts +++ b/packages/app/src/cli/services/dev/select-store.ts @@ -175,9 +175,8 @@ async function convertStoreToTransferDisabled( shopId: store.shopId, }, } - const result: ConvertDevToTransferDisabledSchema = await developerPlatformClient.convertToTransferDisabledStore( - variables, - ) + const result: ConvertDevToTransferDisabledSchema = + await developerPlatformClient.convertToTransferDisabledStore(variables) if (!result.convertDevToTestStore.convertedToTestStore) { const errors = result.convertDevToTestStore.userErrors.map((error) => error.message).join(', ') throw new BugError( diff --git a/packages/app/src/cli/services/dev/urls.ts b/packages/app/src/cli/services/dev/urls.ts index 977ed669e0f..859a2dc855d 100644 --- a/packages/app/src/cli/services/dev/urls.ts +++ b/packages/app/src/cli/services/dev/urls.ts @@ -87,7 +87,7 @@ export async function generateFrontendURL(options: FrontendURLOptions): Promise< throw new AbortError(`Invalid tunnel URL: ${options.tunnelUrl}`, 'Valid format: "https://my-tunnel-url:port"') } frontendPort = Number(matches[2]) - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + frontendUrl = matches[1]! return {frontendUrl, frontendPort, usingLocalhost} } diff --git a/packages/app/src/cli/services/execute-operation.test.ts b/packages/app/src/cli/services/execute-operation.test.ts index eb503d1f82d..03af22d7d2e 100644 --- a/packages/app/src/cli/services/execute-operation.test.ts +++ b/packages/app/src/cli/services/execute-operation.test.ts @@ -343,9 +343,8 @@ describe('executeOperation', () => { const mutation = 'mutation { productUpdate(input: {}) { product { id } } }' // Import the real validateMutationStore to test end-to-end validation - const {validateMutationStore: realValidateMutationStore} = await vi.importActual< - typeof import('./graphql/common.js') - >('./graphql/common.js') + const {validateMutationStore: realValidateMutationStore} = + await vi.importActual('./graphql/common.js') vi.mocked(validateMutationStore).mockImplementation((query, store) => realValidateMutationStore(query, store)) await expect( diff --git a/packages/app/src/cli/services/function/build.ts b/packages/app/src/cli/services/function/build.ts index d5e0e1bb2da..666724ee461 100644 --- a/packages/app/src/cli/services/function/build.ts +++ b/packages/app/src/cli/services/function/build.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ import { downloadBinary, javyBinary, diff --git a/packages/app/src/cli/services/function/replay.ts b/packages/app/src/cli/services/function/replay.ts index f8954feac1c..29cb6796fb6 100644 --- a/packages/app/src/cli/services/function/replay.ts +++ b/packages/app/src/cli/services/function/replay.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ import {renderReplay} from './ui.js' import {runFunction} from './runner.js' import {AppLinkedInterface} from '../../models/app/app.js' diff --git a/packages/app/src/cli/services/generate-schema.ts b/packages/app/src/cli/services/generate-schema.ts index b611831015a..b46be1601f3 100644 --- a/packages/app/src/cli/services/generate-schema.ts +++ b/packages/app/src/cli/services/generate-schema.ts @@ -27,7 +27,7 @@ export async function generateSchemaService(options: GenerateSchemaOptions) { localIdentifier: extension.localIdentifier, developerPlatformClient, apiKey, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + target: targeting![0]!.target, version, orgId, diff --git a/packages/app/src/cli/services/generate.ts b/packages/app/src/cli/services/generate.ts index 038e7e5367d..50c6cc5bfd1 100644 --- a/packages/app/src/cli/services/generate.ts +++ b/packages/app/src/cli/services/generate.ts @@ -1,4 +1,10 @@ import {fetchExtensionTemplates} from './generate/fetch-template-specifications.js' +import { + GenerateExtensionTemplateOptions, + GeneratedExtension, + generateExtensionTemplate, + ExtensionFlavorValue, +} from './generate/extension.js' import {DeveloperPlatformClient} from '../utilities/developer-platform-client.js' import {AppInterface, AppLinkedInterface} from '../models/app/app.js' import generateExtensionPrompts, { @@ -6,12 +12,6 @@ import generateExtensionPrompts, { GenerateExtensionPromptOutput, } from '../prompts/generate/extension.js' import metadata from '../metadata.js' -import { - GenerateExtensionTemplateOptions, - GeneratedExtension, - generateExtensionTemplate, - ExtensionFlavorValue, -} from '../services/generate/extension.js' import {ExtensionTemplate} from '../models/app/template.js' import {ExtensionSpecification, RemoteAwareExtensionSpecification} from '../models/extensions/specification.js' import {OrganizationApp} from '../models/organization.js' @@ -159,7 +159,6 @@ function formatSuccessfulRunMessage( } if (extensionTemplate.type !== 'function') { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion options.nextSteps!.push([ 'To preview this extension along with the rest of the project, run', {command: formatPackageManagerCommand(depndencyManager, 'shopify app dev')}, @@ -167,7 +166,6 @@ function formatSuccessfulRunMessage( } if (extensionTemplate.supportLinks[0]) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion options.reference!.push([ 'For more details, see the', {link: {label: 'docs', url: extensionTemplate.supportLinks[0]}}, diff --git a/packages/app/src/cli/services/graphql/common.ts b/packages/app/src/cli/services/graphql/common.ts index 48127580370..12d237f9e1d 100644 --- a/packages/app/src/cli/services/graphql/common.ts +++ b/packages/app/src/cli/services/graphql/common.ts @@ -78,7 +78,6 @@ export async function resolveApiVersion(options: ResolveApiVersionOptions): Prom supportedVersions.push(minimumDefaultVersion) } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion return supportedVersions.sort().reverse()[0]! } diff --git a/packages/app/src/cli/services/import-extensions.ts b/packages/app/src/cli/services/import-extensions.ts index 2d736b0b0c6..9234404fdc7 100644 --- a/packages/app/src/cli/services/import-extensions.ts +++ b/packages/app/src/cli/services/import-extensions.ts @@ -97,7 +97,6 @@ export async function importExtensions(options: ImportOptions) { const promptAnswer = await renderSelectPrompt({message: 'Extensions to migrate', choices}) if (promptAnswer !== 'All') { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion extensionsToMigrate = [extensionsToMigrate.find((ext) => ext?.uuid === promptAnswer)!] } } diff --git a/packages/app/src/cli/services/web.ts b/packages/app/src/cli/services/web.ts index c4fe751b491..e82197acf35 100644 --- a/packages/app/src/cli/services/web.ts +++ b/packages/app/src/cli/services/web.ts @@ -21,7 +21,7 @@ export default async function web( } const [cmd, ...args] = script.split(' ') - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + await exec(cmd!, args, {cwd: web.directory, stdout, stderr, signal, env}) stdout.write('Web successfully built.') } diff --git a/packages/app/src/cli/services/webhook/send-app-uninstalled-webhook.ts b/packages/app/src/cli/services/webhook/send-app-uninstalled-webhook.ts index a8581936c01..95ed3f37610 100644 --- a/packages/app/src/cli/services/webhook/send-app-uninstalled-webhook.ts +++ b/packages/app/src/cli/services/webhook/send-app-uninstalled-webhook.ts @@ -22,7 +22,7 @@ export async function sendUninstallWebhookToAppServer( const apiVersions = await requestApiVersions(options.developerPlatformClient, options.organizationId) const variables: SendSampleWebhookVariables = { topic: 'app/uninstalled', - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + api_version: apiVersions[1]!, address: options.address, delivery_method: DELIVERY_METHOD.LOCALHOST, diff --git a/packages/app/src/cli/services/webhook/trigger-options.ts b/packages/app/src/cli/services/webhook/trigger-options.ts index 26ca2da3838..10af1c04be3 100644 --- a/packages/app/src/cli/services/webhook/trigger-options.ts +++ b/packages/app/src/cli/services/webhook/trigger-options.ts @@ -46,7 +46,6 @@ export async function collectCredentials( configFile: basename(app.configuration.path), }) - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const clientSecret = remoteApp.apiSecretKeys.find((elm) => elm.secret)!.secret return { clientSecret, diff --git a/packages/app/src/cli/utilities/developer-platform-client/app-management-client.ts b/packages/app/src/cli/utilities/developer-platform-client/app-management-client.ts index 410c61f9028..f2ca5f2cdee 100644 --- a/packages/app/src/cli/utilities/developer-platform-client/app-management-client.ts +++ b/packages/app/src/cli/utilities/developer-platform-client/app-management-client.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ import { OrganizationBetaFlagsQuerySchema, OrganizationBetaFlagsQueryVariables, diff --git a/packages/app/src/cli/utilities/developer-platform-client/partners-client.ts b/packages/app/src/cli/utilities/developer-platform-client/partners-client.ts index 7d61dcc1f1c..c1ecc08c367 100644 --- a/packages/app/src/cli/utilities/developer-platform-client/partners-client.ts +++ b/packages/app/src/cli/utilities/developer-platform-client/partners-client.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ import {CreateAppQuery, CreateAppQuerySchema, CreateAppQueryVariables} from '../../api/graphql/create_app.js' import { AppVersion, @@ -14,7 +13,7 @@ import { AppLogsResponse, createUnauthorizedHandler, } from '../developer-platform-client.js' -import {fetchCurrentAccountInformation} from '../../../cli/services/context/partner-account-info.js' +import {fetchCurrentAccountInformation} from '../../services/context/partner-account-info.js' import { MinimalAppIdentifiers, MinimalOrganizationApp, diff --git a/packages/app/src/cli/utilities/extensions/fetch-product-variant.ts b/packages/app/src/cli/utilities/extensions/fetch-product-variant.ts index 74d206e78f1..2308b0e12b4 100644 --- a/packages/app/src/cli/utilities/extensions/fetch-product-variant.ts +++ b/packages/app/src/cli/utilities/extensions/fetch-product-variant.ts @@ -26,7 +26,7 @@ export async function fetchProductVariant(store: string) { `Your store needs to have at least one product to test a 'checkout_ui' extension.\n\n${addProductLink}`, ) } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const variantURL = result.products.edges[0]!.node.variants.edges[0]!.node.id const variantId = variantURL.split('/').pop() return variantId diff --git a/packages/cli-kit/bin/refresh-code-documentation.ts b/packages/cli-kit/bin/refresh-code-documentation.ts index 02693e11cc9..927f9b76076 100644 --- a/packages/cli-kit/bin/refresh-code-documentation.ts +++ b/packages/cli-kit/bin/refresh-code-documentation.ts @@ -91,7 +91,7 @@ refreshDocumentation() .then(() => { process.exit(0) }) - // eslint-disable-next-line node/handle-callback-err + // eslint-disable-next-line n/handle-callback-err .catch((_error) => { process.exit(1) }) diff --git a/packages/cli-kit/src/cli/api/graphql/admin/generated/types.d.ts b/packages/cli-kit/src/cli/api/graphql/admin/generated/types.d.ts index 3ecac10dacd..73e1c7fd1a9 100644 --- a/packages/cli-kit/src/cli/api/graphql/admin/generated/types.d.ts +++ b/packages/cli-kit/src/cli/api/graphql/admin/generated/types.d.ts @@ -1,53 +1,52 @@ -/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any, tsdoc/syntax, @nx/enforce-module-boundaries */ +/* eslint-disable @typescript-eslint/consistent-type-definitions, @typescript-eslint/naming-convention, @typescript-eslint/no-explicit-any, tsdoc/syntax, @typescript-eslint/no-duplicate-type-constituents, @typescript-eslint/no-redundant-type-constituents, @nx/enforce-module-boundaries */ import {JsonMapType} from '@shopify/cli-kit/node/toml' - -export type Maybe = T | null -export type InputMaybe = Maybe -export type Exact = {[K in keyof T]: T[K]} -export type MakeOptional = Omit & {[SubKey in K]?: Maybe} -export type MakeMaybe = Omit & {[SubKey in K]: Maybe} -export type MakeEmpty = {[_ in K]?: never} -export type Incremental = T | {[P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never} +export type Maybe = T | null; +export type InputMaybe = Maybe; +export type Exact = { [K in keyof T]: T[K] }; +export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; +export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; +export type MakeEmpty = { [_ in K]?: never }; +export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { - ID: {input: string; output: string} - String: {input: string; output: string} - Boolean: {input: boolean; output: boolean} - Int: {input: number; output: number} - Float: {input: number; output: number} + ID: { input: string; output: string; } + String: { input: string; output: string; } + Boolean: { input: boolean; output: boolean; } + Int: { input: number; output: number; } + Float: { input: number; output: number; } /** * An Amazon Web Services Amazon Resource Name (ARN), including the Region and account ID. * For more information, refer to [Amazon Resource Names](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html). */ - ARN: {input: any; output: any} + ARN: { input: any; output: any; } /** * Represents non-fractional signed whole numeric values. Since the value may * exceed the size of a 32-bit integer, it's encoded as a string. */ - BigInt: {input: any; output: any} + BigInt: { input: any; output: any; } /** * A string containing a hexadecimal representation of a color. * * For example, "#6A8D48". */ - Color: {input: any; output: any} + Color: { input: any; output: any; } /** * Represents an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)-encoded date string. * For example, September 7, 2019 is represented as `"2019-07-16"`. */ - Date: {input: any; output: any} + Date: { input: any; output: any; } /** * Represents an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601)-encoded date and time string. * For example, 3:50 pm on September 7, 2019 in the time zone of UTC (Coordinated Universal Time) is * represented as `"2019-09-07T15:50:00Z`". */ - DateTime: {input: any; output: any} + DateTime: { input: any; output: any; } /** * A signed decimal number, which supports arbitrary precision and is serialized as a string. * * Example values: `"29.99"`, `"29.999"`. */ - Decimal: {input: any; output: any} + Decimal: { input: any; output: any; } /** * A string containing a strict subset of HTML code. Non-allowed tags will be stripped out. * Allowed tags: @@ -63,14 +62,14 @@ export type Scalars = { * * Example value: `"Your current domain is example.myshopify.com."` */ - FormattedString: {input: any; output: any} + FormattedString: { input: any; output: any; } /** * A string containing HTML code. Refer to the [HTML spec](https://html.spec.whatwg.org/#elements-3) for a * complete list of HTML elements. * * Example value: `"

Grey cotton knit sweater.

"` */ - HTML: {input: any; output: any} + HTML: { input: any; output: any; } /** * A [JSON](https://www.json.org/json-en.html) object. * @@ -86,16 +85,16 @@ export type Scalars = { * } * }` */ - JSON: {input: JsonMapType | string; output: JsonMapType} + JSON: { input: JsonMapType | string; output: JsonMapType; } /** A monetary value string without a currency symbol or code. Example value: `"100.57"`. */ - Money: {input: any; output: any} + Money: { input: any; output: any; } /** * Represents a unique identifier in the Storefront API. A `StorefrontID` value can * be used wherever an ID is expected in the Storefront API. * * Example value: `"Z2lkOi8vc2hvcGlmeS9Qcm9kdWN0LzEwMDc5Nzg1MTAw"`. */ - StorefrontID: {input: any; output: any} + StorefrontID: { input: any; output: any; } /** * Represents an [RFC 3986](https://datatracker.ietf.org/doc/html/rfc3986) and * [RFC 3987](https://datatracker.ietf.org/doc/html/rfc3987)-compliant URI string. @@ -103,20 +102,20 @@ export type Scalars = { * For example, `"https://example.myshopify.com"` is a valid URL. It includes a scheme (`https`) and a host * (`example.myshopify.com`). */ - URL: {input: string; output: string} + URL: { input: string; output: string; } /** * An unsigned 64-bit integer. Represents whole numeric values between 0 and 2^64 - 1 encoded as a string of base-10 digits. * * Example value: `"50"`. */ - UnsignedInt64: {input: any; output: any} + UnsignedInt64: { input: any; output: any; } /** * Time between UTC time and a location's observed time, in the format `"+HH:MM"` or `"-HH:MM"`. * * Example value: `"-07:00"`. */ - UtcOffset: {input: any; output: any} -} + UtcOffset: { input: any; output: any; } +}; /** Possible types of a metafield's owner resource. */ export type MetafieldOwnerType = @@ -173,15 +172,15 @@ export type MetafieldOwnerType = /** The Shop metafield owner type. */ | 'SHOP' /** The Validation metafield owner type. */ - | 'VALIDATION' + | 'VALIDATION'; /** The input fields for the theme file body. */ export type OnlineStoreThemeFileBodyInput = { /** The input type of the theme file body. */ - type: OnlineStoreThemeFileBodyInputType + type: OnlineStoreThemeFileBodyInputType; /** The body of the theme file. */ - value: Scalars['String']['input'] -} + value: Scalars['String']['input']; +}; /** The input type for a theme file body. */ export type OnlineStoreThemeFileBodyInputType = @@ -190,7 +189,7 @@ export type OnlineStoreThemeFileBodyInputType = /** The text body of the theme file. */ | 'TEXT' /** The url of the body of a theme file. */ - | 'URL' + | 'URL'; /** Type of a theme file operation result. */ export type OnlineStoreThemeFileResultType = @@ -207,15 +206,15 @@ export type OnlineStoreThemeFileResultType = /** Operation timed out. */ | 'TIMEOUT' /** Operation could not be processed due to issues with input data. */ - | 'UNPROCESSABLE_ENTITY' + | 'UNPROCESSABLE_ENTITY'; /** The input fields for the file to create or update. */ export type OnlineStoreThemeFilesUpsertFileInput = { /** The body of the theme file. */ - body: OnlineStoreThemeFileBodyInput + body: OnlineStoreThemeFileBodyInput; /** The filename of the theme file. */ - filename: Scalars['String']['input'] -} + filename: Scalars['String']['input']; +}; /** Possible error codes that can be returned by `OnlineStoreThemeFilesUserErrors`. */ export type OnlineStoreThemeFilesUserErrorsCode = @@ -236,13 +235,13 @@ export type OnlineStoreThemeFilesUserErrorsCode = /** This action is not available on your current plan. Please upgrade to access theme editing features. */ | 'THEME_LIMITED_PLAN' /** Too many updates in a short period. Please try again later. */ - | 'THROTTLED' + | 'THROTTLED'; /** The input fields for Theme attributes to update. */ export type OnlineStoreThemeInput = { /** The new name of the theme. */ - name?: InputMaybe -} + name?: InputMaybe; +}; /** The role of the theme. */ export type ThemeRole = @@ -270,4 +269,4 @@ export type ThemeRole = /** The currently published theme that is only accessible to a mobile client. */ | 'MOBILE' /** The theme is currently not published. It can be transitioned to the main role if it is published by the merchant. */ - | 'UNPUBLISHED' + | 'UNPUBLISHED'; diff --git a/packages/cli-kit/src/private/node/analytics.ts b/packages/cli-kit/src/private/node/analytics.ts index 67a869ee8d8..3034d8c1eff 100644 --- a/packages/cli-kit/src/private/node/analytics.ts +++ b/packages/cli-kit/src/private/node/analytics.ts @@ -9,6 +9,7 @@ import {ciPlatform, cloudEnvironment, macAddress} from '../../public/node/contex import {cwd} from '../../public/node/path.js' import {currentProcessIsGlobal} from '../../public/node/is-global.js' import {isWsl} from '../../public/node/system.js' + import {Command, Interfaces} from '@oclif/core' interface StartOptions { diff --git a/packages/cli-kit/src/private/node/analytics/bounded-collections.ts b/packages/cli-kit/src/private/node/analytics/bounded-collections.ts index 9328c26114b..6036696a901 100644 --- a/packages/cli-kit/src/private/node/analytics/bounded-collections.ts +++ b/packages/cli-kit/src/private/node/analytics/bounded-collections.ts @@ -84,7 +84,7 @@ export class BMap extends Map { super.clear() } - toObject(): {[key: string]: TValue} { + toObject(): Record { return Object.fromEntries(this) } diff --git a/packages/cli-kit/src/private/node/analytics/error-categorizer.ts b/packages/cli-kit/src/private/node/analytics/error-categorizer.ts index 1918e068c30..3bb4ad97a74 100644 --- a/packages/cli-kit/src/private/node/analytics/error-categorizer.ts +++ b/packages/cli-kit/src/private/node/analytics/error-categorizer.ts @@ -64,7 +64,7 @@ export function formatErrorMessage(error: unknown, category: ErrorCategory): str return formatter(message) } -const ERROR_FORMATTERS: {[key in ErrorCategory]: (message: string) => string} = { +const ERROR_FORMATTERS: Record string> = { [ErrorCategory.Network]: formatNetworkError, [ErrorCategory.Authentication]: formatGenericError, [ErrorCategory.FileSystem]: formatGenericError, diff --git a/packages/cli-kit/src/private/node/api.ts b/packages/cli-kit/src/private/node/api.ts index 6a493350e23..044dd0abfb2 100644 --- a/packages/cli-kit/src/private/node/api.ts +++ b/packages/cli-kit/src/private/node/api.ts @@ -3,8 +3,10 @@ import {sanitizeURL} from './api/urls.js' import {sleepWithBackoffUntil} from './sleep-with-backoff.js' import {outputDebug} from '../../public/node/output.js' import {recordRetry} from '../../public/node/analytics.js' + import {Headers} from 'form-data' import {ClientError} from 'graphql-request' + import {performance} from 'perf_hooks' export type API = 'admin' | 'storefront-renderer' | 'partners' | 'business-platform' | 'app-management' @@ -169,7 +171,7 @@ async function makeVerboseRequest( ): Promise> { const t0 = performance.now() let duration = 0 - const responseHeaders: {[key: string]: string} = {} + const responseHeaders: Record = {} const sanitizedUrl = sanitizeURL(requestOptions.url) let response: T = {} as T try { diff --git a/packages/cli-kit/src/private/node/api/graphql.ts b/packages/cli-kit/src/private/node/api/graphql.ts index 9a0136db2c6..b9272bf61dd 100644 --- a/packages/cli-kit/src/private/node/api/graphql.ts +++ b/packages/cli-kit/src/private/node/api/graphql.ts @@ -2,6 +2,7 @@ import {GraphQLClientError, sanitizedHeadersOutput} from './headers.js' import {sanitizeURL} from './urls.js' import {stringifyMessage, outputContent, outputToken, outputDebug} from '../../../public/node/output.js' import {AbortError} from '../../../public/node/error.js' + import {ClientError, Variables} from 'graphql-request' export function debugLogRequestInfo( @@ -9,7 +10,7 @@ export function debugLogRequestInfo( query: string, url: string, variables?: Variables, - headers: {[key: string]: string} = {}, + headers: Record = {}, ) { outputDebug(outputContent`Sending ${outputToken.json(api)} GraphQL request: ${outputToken.raw(query.toString().trim())} diff --git a/packages/cli-kit/src/private/node/api/headers.test.ts b/packages/cli-kit/src/private/node/api/headers.test.ts index be8ca5ff495..13441e6a5a0 100644 --- a/packages/cli-kit/src/private/node/api/headers.test.ts +++ b/packages/cli-kit/src/private/node/api/headers.test.ts @@ -2,6 +2,7 @@ import {buildHeaders, sanitizedHeadersOutput, GraphQLClientError} from './header import {CLI_KIT_VERSION} from '../../../public/common/version.js' import {randomUUID} from '../../../public/node/crypto.js' import {firstPartyDev, isUnitTest} from '../../../public/node/context/local.js' + import {test, vi, expect, describe, beforeEach} from 'vitest' vi.mock('../../../public/node/crypto.js') diff --git a/packages/cli-kit/src/private/node/api/headers.ts b/packages/cli-kit/src/private/node/api/headers.ts index e743b3258c2..691505dc9e8 100644 --- a/packages/cli-kit/src/private/node/api/headers.ts +++ b/packages/cli-kit/src/private/node/api/headers.ts @@ -31,12 +31,11 @@ export class GraphQLClientError extends RequestClientError { * @param headers - HTTP headers. * @returns A sanitized version of the headers as a string. */ -export function sanitizedHeadersOutput(headers: {[key: string]: string}): string { - const sanitized: {[key: string]: string} = {} +export function sanitizedHeadersOutput(headers: Record): string { + const sanitized: Record = {} const keywords = ['token', 'authorization', 'subject_token'] Object.keys(headers).forEach((header) => { if (keywords.find((keyword) => header.toLocaleLowerCase().includes(keyword)) === undefined) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion sanitized[header] = headers[header]! } }) @@ -47,10 +46,10 @@ export function sanitizedHeadersOutput(headers: {[key: string]: string}): string .join('\n') } -export function buildHeaders(token?: string): {[key: string]: string} { +export function buildHeaders(token?: string): Record { const userAgent = `Shopify CLI; v=${CLI_KIT_VERSION}` - const headers: {[header: string]: string} = { + const headers: Record = { 'User-Agent': userAgent, 'Keep-Alive': 'timeout=30', // 'Sec-CH-UA': secCHUA, This header requires the Git sha. diff --git a/packages/cli-kit/src/private/node/api/rest.ts b/packages/cli-kit/src/private/node/api/rest.ts index c87f3131c5a..b49c50b4dd1 100644 --- a/packages/cli-kit/src/private/node/api/rest.ts +++ b/packages/cli-kit/src/private/node/api/rest.ts @@ -13,7 +13,7 @@ export function restRequestUrl( session: AdminSession, apiVersion: string, path: string, - searchParams: {[name: string]: string} = {}, + searchParams: Record = {}, ) { const url = new URL( isThemeAccessSession(session) diff --git a/packages/cli-kit/src/private/node/conf-store.test.ts b/packages/cli-kit/src/private/node/conf-store.test.ts index 8e714a34062..444776ab715 100644 --- a/packages/cli-kit/src/private/node/conf-store.test.ts +++ b/packages/cli-kit/src/private/node/conf-store.test.ts @@ -16,6 +16,7 @@ import { } from './conf-store.js' import {LocalStorage} from '../../public/node/local-storage.js' import {inTemporaryDirectory} from '../../public/node/fs.js' + import {afterEach, beforeEach, describe, expect, test, vi} from 'vitest' describe('getSession', () => { diff --git a/packages/cli-kit/src/private/node/conf-store.ts b/packages/cli-kit/src/private/node/conf-store.ts index e5cae2306de..1bc85399fd5 100644 --- a/packages/cli-kit/src/private/node/conf-store.ts +++ b/packages/cli-kit/src/private/node/conf-store.ts @@ -257,7 +257,7 @@ export async function runWithRateLimit(options: RunWithRateLimitOptions, config } export function getConfigStoreForPartnerStatus() { - return new LocalStorage<{[partnerToken: string]: {status: true; checkedAt: string}}>({ + return new LocalStorage>({ projectName: 'shopify-cli-kit-partner-status', }) } diff --git a/packages/cli-kit/src/private/node/session.test.ts b/packages/cli-kit/src/private/node/session.test.ts index a48945980c3..08eda6acff3 100644 --- a/packages/cli-kit/src/private/node/session.test.ts +++ b/packages/cli-kit/src/private/node/session.test.ts @@ -27,6 +27,7 @@ import {businessPlatformRequest} from '../../public/node/api/business-platform.j import {getPartnersToken} from '../../public/node/environment.js' import {nonRandomUUID} from '../../public/node/crypto.js' import {terminalSupportsPrompting} from '../../public/node/system.js' + import {vi, describe, expect, test, beforeEach} from 'vitest' const futureDate = new Date(2022, 1, 1, 11) @@ -55,7 +56,7 @@ const validTokens: OAuthSession = { userId, } -const appTokens: {[x: string]: ApplicationToken} = { +const appTokens: Record = { // Admin APIs includes domain in the key 'mystore.myshopify.com-admin': { accessToken: 'admin_token', diff --git a/packages/cli-kit/src/private/node/session.ts b/packages/cli-kit/src/private/node/session.ts index 41409c83e69..46d48594c45 100644 --- a/packages/cli-kit/src/private/node/session.ts +++ b/packages/cli-kit/src/private/node/session.ts @@ -234,7 +234,6 @@ ${outputToken.json(applications)} } else if (validationResult === 'needs_refresh' || forceRefresh) { outputDebug(outputContent`The current session is valid but needs refresh. Refreshing...`) try { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion newSession = await refreshTokens(currentSession!, applications) } catch (error) { if (error instanceof InvalidGrantError) { diff --git a/packages/cli-kit/src/private/node/session/device-authorization.test.ts b/packages/cli-kit/src/private/node/session/device-authorization.test.ts index d3c2b0f718a..32349ba0ee2 100644 --- a/packages/cli-kit/src/private/node/session/device-authorization.test.ts +++ b/packages/cli-kit/src/private/node/session/device-authorization.test.ts @@ -12,6 +12,7 @@ import {isTTY} from '../../../public/node/ui.js' import {err, ok} from '../../../public/node/result.js' import {AbortError} from '../../../public/node/error.js' import {isCI} from '../../../public/node/system.js' + import {beforeEach, describe, expect, test, vi} from 'vitest' import {Response} from 'node-fetch' diff --git a/packages/cli-kit/src/private/node/session/device-authorization.ts b/packages/cli-kit/src/private/node/session/device-authorization.ts index e875adf1ea8..14e8e367a9f 100644 --- a/packages/cli-kit/src/private/node/session/device-authorization.ts +++ b/packages/cli-kit/src/private/node/session/device-authorization.ts @@ -8,6 +8,7 @@ import {AbortError, BugError} from '../../../public/node/error.js' import {isCloudEnvironment} from '../../../public/node/context/local.js' import {isCI, openURL} from '../../../public/node/system.js' import {isTTY, keypress} from '../../../public/node/ui.js' + import {Response} from 'node-fetch' export interface DeviceAuthorizationResponse { diff --git a/packages/cli-kit/src/private/node/session/exchange.test.ts b/packages/cli-kit/src/private/node/session/exchange.test.ts index fd2bebebabd..22befb2f7bc 100644 --- a/packages/cli-kit/src/private/node/session/exchange.test.ts +++ b/packages/cli-kit/src/private/node/session/exchange.test.ts @@ -14,6 +14,7 @@ import {shopifyFetch} from '../../../public/node/http.js' import {identityFqdn} from '../../../public/node/context/fqdn.js' import {getLastSeenUserIdAfterAuth, getLastSeenAuthMethod} from '../session.js' import {AbortError} from '../../../public/node/error.js' + import {describe, test, expect, vi, afterAll, beforeEach} from 'vitest' import {Response} from 'node-fetch' @@ -271,7 +272,6 @@ describe.each(tokenExchangeMethods)( // Given let capturedUrl = '' vi.mocked(shopifyFetch).mockImplementation(async (url, options) => { - // eslint-disable-next-line @typescript-eslint/no-base-to-string capturedUrl = url.toString() return Promise.resolve( new Response( diff --git a/packages/cli-kit/src/private/node/session/exchange.ts b/packages/cli-kit/src/private/node/session/exchange.ts index 1fcb3024eea..fc0143aefe3 100644 --- a/packages/cli-kit/src/private/node/session/exchange.ts +++ b/packages/cli-kit/src/private/node/session/exchange.ts @@ -8,6 +8,7 @@ import {err, ok, Result} from '../../../public/node/result.js' import {AbortError, BugError, ExtendableError} from '../../../public/node/error.js' import {setLastSeenAuthMethod, setLastSeenUserIdAfterAuth} from '../session.js' import {nonRandomUUID} from '../../../public/node/crypto.js' + import * as jose from 'jose' export class InvalidGrantError extends ExtendableError {} @@ -32,7 +33,7 @@ export async function exchangeAccessForApplicationTokens( identityToken: IdentityToken, scopes: ExchangeScopes, store?: string, -): Promise<{[x: string]: ApplicationToken}> { +): Promise> { const token = identityToken.accessToken const [partners, storefront, businessPlatform, admin, appManagement] = await Promise.all([ @@ -83,7 +84,7 @@ async function exchangeCliTokenForAccessToken( const appId = applicationId(apiName) try { const newToken = await requestAppToken(apiName, token, scopes) - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const accessToken = newToken[appId]!.accessToken const userId = nonRandomUUID(token) setLastSeenUserIdAfterAuth(userId) @@ -162,7 +163,7 @@ export async function requestAppToken( token: string, scopes: string[] = [], store?: string, -): Promise<{[x: string]: ApplicationToken}> { +): Promise> { const appId = applicationId(api) const clientId = await getIdentityClientId() @@ -221,9 +222,9 @@ function tokenRequestErrorHandler({error, store}: {error: string; store?: string return new AbortError(error) } -async function tokenRequest(params: { - [key: string]: string -}): Promise> { +async function tokenRequest( + params: Record, +): Promise> { const fqdn = await identityFqdn() const url = new URL(`https://${fqdn}/oauth/token`) url.search = new URLSearchParams(Object.entries(params)).toString() @@ -242,7 +243,6 @@ function buildIdentityToken( existingUserId?: string, existingAlias?: string, ): IdentityToken { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const userId = existingUserId ?? (result.id_token ? jose.decodeJwt(result.id_token).sub! : undefined) if (!userId) { diff --git a/packages/cli-kit/src/private/node/session/store.test.ts b/packages/cli-kit/src/private/node/session/store.test.ts index 429c2d842c5..625163c1ab5 100644 --- a/packages/cli-kit/src/private/node/session/store.test.ts +++ b/packages/cli-kit/src/private/node/session/store.test.ts @@ -2,6 +2,7 @@ import {Sessions} from './schema.js' import {store, fetch, remove, getSessionAlias, findSessionByAlias} from './store.js' import {getSessions, removeSessions, setSessions, removeCurrentSessionId} from '../conf-store.js' import {identityFqdn} from '../../../public/node/context/fqdn.js' + import {describe, expect, vi, test, beforeEach} from 'vitest' vi.mock('../conf-store.js') diff --git a/packages/cli-kit/src/private/node/session/validate.ts b/packages/cli-kit/src/private/node/session/validate.ts index 2dd97f2480e..d4b79799284 100644 --- a/packages/cli-kit/src/private/node/session/validate.ts +++ b/packages/cli-kit/src/private/node/session/validate.ts @@ -1,6 +1,6 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ -import {applicationId} from './identity.js' import {ApplicationToken, IdentityToken, Session, validateCachedIdentityTokenStructure} from './schema.js' + +import {applicationId} from './identity.js' import {sessionConstants} from '../constants.js' import {firstPartyDev} from '../../../public/node/context/local.js' import {OAuthApplications} from '../session.js' diff --git a/packages/cli-kit/src/private/node/testing/ui.ts b/packages/cli-kit/src/private/node/testing/ui.ts index 70c7fa9ffc9..9fb0590cd9f 100644 --- a/packages/cli-kit/src/private/node/testing/ui.ts +++ b/packages/cli-kit/src/private/node/testing/ui.ts @@ -2,6 +2,7 @@ import {isTruthy} from '../../../public/node/context/utilities.js' import {Stdout} from '../ui.js' import {ReactElement} from 'react' import {render as inkRender} from 'ink' + import {EventEmitter} from 'events' class Stderr extends EventEmitter { diff --git a/packages/cli-kit/src/private/node/themes/generate-theme-name.ts b/packages/cli-kit/src/private/node/themes/generate-theme-name.ts index 07e6d4aafcc..a44a93f3d96 100644 --- a/packages/cli-kit/src/private/node/themes/generate-theme-name.ts +++ b/packages/cli-kit/src/private/node/themes/generate-theme-name.ts @@ -5,7 +5,6 @@ import {hostname} from 'os' export const API_NAME_LIMIT = 50 export function generateThemeName(context: string): string { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const hostNameWithoutDomain = hostname().split('.')[0]! const hash = randomBytes(3).toString('hex') diff --git a/packages/cli-kit/src/private/node/ui.tsx b/packages/cli-kit/src/private/node/ui.tsx index 7df2c5e09ee..aecaced5571 100644 --- a/packages/cli-kit/src/private/node/ui.tsx +++ b/packages/cli-kit/src/private/node/ui.tsx @@ -2,8 +2,10 @@ import {output} from './output.js' import {Logger, LogLevel} from '../../public/node/output.js' import {isUnitTest} from '../../public/node/context/local.js' import {treeKill} from '../../public/node/tree-kill.js' + import {ReactElement} from 'react' import {Key, render as inkRender, RenderOptions} from 'ink' + import {EventEmitter} from 'events' interface RenderOnceOptions { diff --git a/packages/cli-kit/src/private/node/ui/alert.tsx b/packages/cli-kit/src/private/node/ui/alert.tsx index 675650c6ae0..ad73332c2c0 100644 --- a/packages/cli-kit/src/private/node/ui/alert.tsx +++ b/packages/cli-kit/src/private/node/ui/alert.tsx @@ -2,9 +2,10 @@ import {Alert, AlertProps} from './components/Alert.js' import {renderOnce} from '../ui.js' import {LogLevel} from '../../../public/node/output.js' import React from 'react' + import {RenderOptions} from 'ink' -const typeToLogLevel: {[key in AlertProps['type']]: LogLevel} = { +const typeToLogLevel: Record = { info: 'info', warning: 'warn', success: 'info', diff --git a/packages/cli-kit/src/private/node/ui/components/Alert.test.tsx b/packages/cli-kit/src/private/node/ui/components/Alert.test.tsx index 18589cb79bb..21eaefb3b01 100644 --- a/packages/cli-kit/src/private/node/ui/components/Alert.test.tsx +++ b/packages/cli-kit/src/private/node/ui/components/Alert.test.tsx @@ -2,6 +2,7 @@ import {Alert} from './Alert.js' import {unstyled} from '../../../../public/node/output.js' import {render} from '../../testing/ui.js' import {describe, expect, test} from 'vitest' + import React from 'react' describe('Alert', async () => { diff --git a/packages/cli-kit/src/private/node/ui/components/AutocompletePrompt.test.tsx b/packages/cli-kit/src/private/node/ui/components/AutocompletePrompt.test.tsx index 44386351e15..d54604ba4c5 100644 --- a/packages/cli-kit/src/private/node/ui/components/AutocompletePrompt.test.tsx +++ b/packages/cli-kit/src/private/node/ui/components/AutocompletePrompt.test.tsx @@ -10,6 +10,7 @@ import { import {Stdout} from '../../ui.js' import {AbortController} from '../../../../public/node/abort.js' import {beforeEach, describe, expect, test, vi} from 'vitest' + import React from 'react' import {useStdout} from 'ink' diff --git a/packages/cli-kit/src/private/node/ui/components/AutocompletePrompt.tsx b/packages/cli-kit/src/private/node/ui/components/AutocompletePrompt.tsx index e44394f8aa0..bc0340c3944 100644 --- a/packages/cli-kit/src/private/node/ui/components/AutocompletePrompt.tsx +++ b/packages/cli-kit/src/private/node/ui/components/AutocompletePrompt.tsx @@ -6,6 +6,7 @@ import {Message, PromptLayout} from './Prompts/PromptLayout.js' import {throttle} from '../../../../public/common/function.js' import {AbortSignal} from '../../../../public/node/abort.js' import usePrompt, {PromptState} from '../hooks/use-prompt.js' + import React, {ReactElement, useCallback, useEffect, useRef, useState} from 'react' import {Box, useApp} from 'ink' @@ -30,7 +31,6 @@ export interface AutocompletePromptProps { const MIN_NUMBER_OF_ITEMS_FOR_SEARCH = 5 -// eslint-disable-next-line react/function-component-definition function AutocompletePrompt({ message, choices, diff --git a/packages/cli-kit/src/private/node/ui/components/Banner.test.tsx b/packages/cli-kit/src/private/node/ui/components/Banner.test.tsx index 9aa12b6b2d0..33e78b6417c 100644 --- a/packages/cli-kit/src/private/node/ui/components/Banner.test.tsx +++ b/packages/cli-kit/src/private/node/ui/components/Banner.test.tsx @@ -1,7 +1,7 @@ -import {Banner} from './Banner.js' import {List} from './List.js' -import {render} from '../../testing/ui.js' +import {Banner} from './Banner.js' import {unstyled} from '../../../../public/node/output.js' +import {render} from '../../testing/ui.js' import {describe, expect, test} from 'vitest' import React from 'react' import {Text} from 'ink' diff --git a/packages/cli-kit/src/private/node/ui/components/Banner.tsx b/packages/cli-kit/src/private/node/ui/components/Banner.tsx index c97f00c2ea5..948306f9648 100644 --- a/packages/cli-kit/src/private/node/ui/components/Banner.tsx +++ b/packages/cli-kit/src/private/node/ui/components/Banner.tsx @@ -41,14 +41,13 @@ const Footnotes = () => { const BoxWithBorder: FunctionComponent = ({type, children}) => { const {twoThirds} = useLayout() - const links = useRef<{[key: string]: Link}>({}) + const links = useRef>({}) return ( { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const id: string | undefined = Object.keys(links.current).find((id) => links.current[id]!.url === url) if (id) { return id diff --git a/packages/cli-kit/src/private/node/ui/components/ConcurrentOutput.test.tsx b/packages/cli-kit/src/private/node/ui/components/ConcurrentOutput.test.tsx index 719c2820dc4..1233bbe5d25 100644 --- a/packages/cli-kit/src/private/node/ui/components/ConcurrentOutput.test.tsx +++ b/packages/cli-kit/src/private/node/ui/components/ConcurrentOutput.test.tsx @@ -2,8 +2,10 @@ import {ConcurrentOutput, useConcurrentOutputContext} from './ConcurrentOutput.j import {render} from '../../testing/ui.js' import {AbortController, AbortSignal} from '../../../../public/node/abort.js' import {unstyled} from '../../../../public/node/output.js' + import React from 'react' import {describe, expect, test} from 'vitest' + import {Writable} from 'stream' /** @@ -104,7 +106,6 @@ describe('ConcurrentOutput', () => { { prefix: '1', action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => { - // eslint-disable-next-line react-hooks/rules-of-hooks useConcurrentOutputContext({stripAnsi: false}, () => { stdout.write(output) }) @@ -131,7 +132,6 @@ describe('ConcurrentOutput', () => { { prefix: '1', action: async (stdout: Writable, _stderr: Writable, _signal: AbortSignal) => { - // eslint-disable-next-line react-hooks/rules-of-hooks useConcurrentOutputContext({outputPrefix: extensionName}, () => { stdout.write('foo bar') }) diff --git a/packages/cli-kit/src/private/node/ui/components/ConcurrentOutput.tsx b/packages/cli-kit/src/private/node/ui/components/ConcurrentOutput.tsx index da83738b860..b0f508259fd 100644 --- a/packages/cli-kit/src/private/node/ui/components/ConcurrentOutput.tsx +++ b/packages/cli-kit/src/private/node/ui/components/ConcurrentOutput.tsx @@ -4,6 +4,7 @@ import React, {FunctionComponent, useCallback, useEffect, useMemo, useState} fro import {Box, Static, Text, TextProps, useApp} from 'ink' import figures from 'figures' import stripAnsi from 'strip-ansi' + import {Writable} from 'stream' import {AsyncLocalStorage} from 'node:async_hooks' diff --git a/packages/cli-kit/src/private/node/ui/components/DangerousConfirmationPrompt.test.tsx b/packages/cli-kit/src/private/node/ui/components/DangerousConfirmationPrompt.test.tsx index b265086218c..b5eb3fc0d7e 100644 --- a/packages/cli-kit/src/private/node/ui/components/DangerousConfirmationPrompt.test.tsx +++ b/packages/cli-kit/src/private/node/ui/components/DangerousConfirmationPrompt.test.tsx @@ -2,6 +2,7 @@ import {DangerousConfirmationPrompt} from './DangerousConfirmationPrompt.js' import {getLastFrameAfterUnmount, sendInputAndWaitForChange, waitForInputsToBeReady, render} from '../../testing/ui.js' import {unstyled} from '../../../../public/node/output.js' import React from 'react' + import {describe, expect, test, vi} from 'vitest' const ENTER = '\r' diff --git a/packages/cli-kit/src/private/node/ui/components/DangerousConfirmationPrompt.tsx b/packages/cli-kit/src/private/node/ui/components/DangerousConfirmationPrompt.tsx index e09a1853e9a..d877dd98440 100644 --- a/packages/cli-kit/src/private/node/ui/components/DangerousConfirmationPrompt.tsx +++ b/packages/cli-kit/src/private/node/ui/components/DangerousConfirmationPrompt.tsx @@ -7,6 +7,7 @@ import {messageWithPunctuation} from '../utilities.js' import {AbortSignal} from '../../../../public/node/abort.js' import useAbortSignal from '../hooks/use-abort-signal.js' import usePrompt, {PromptState} from '../hooks/use-prompt.js' + import React, {FunctionComponent, useCallback, useEffect, useState} from 'react' import {Box, useApp, useInput, Text} from 'ink' import figures from 'figures' diff --git a/packages/cli-kit/src/private/node/ui/components/FatalError.test.tsx b/packages/cli-kit/src/private/node/ui/components/FatalError.test.tsx index af7b6755be3..51721c0a06d 100644 --- a/packages/cli-kit/src/private/node/ui/components/FatalError.test.tsx +++ b/packages/cli-kit/src/private/node/ui/components/FatalError.test.tsx @@ -3,6 +3,7 @@ import {unstyled} from '../../../../public/node/output.js' import {AbortError, BugError, ExternalError} from '../../../../public/node/error.js' import {render} from '../../testing/ui.js' import {describe, expect, test} from 'vitest' + import React from 'react' describe('FatalError', async () => { diff --git a/packages/cli-kit/src/private/node/ui/components/FatalError.tsx b/packages/cli-kit/src/private/node/ui/components/FatalError.tsx index b632ac0d177..f8876fab6ea 100644 --- a/packages/cli-kit/src/private/node/ui/components/FatalError.tsx +++ b/packages/cli-kit/src/private/node/ui/components/FatalError.tsx @@ -30,7 +30,7 @@ const FatalError: FunctionComponent = ({error}) => { .map((item) => { /** We make the paths relative to the packages/ directory */ const fileShortComponents = item.fileShort.split('packages/') - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + item.fileShort = fileShortComponents.length === 2 ? fileShortComponents[1]! : fileShortComponents[0]! return item }) diff --git a/packages/cli-kit/src/private/node/ui/components/List.test.tsx b/packages/cli-kit/src/private/node/ui/components/List.test.tsx index 1b91c3950ae..d8a35df8427 100644 --- a/packages/cli-kit/src/private/node/ui/components/List.test.tsx +++ b/packages/cli-kit/src/private/node/ui/components/List.test.tsx @@ -2,6 +2,7 @@ import {List} from './List.js' import {unstyled} from '../../../../public/node/output.js' import {render} from '../../testing/ui.js' import {describe, expect, test} from 'vitest' + import React from 'react' describe('List', async () => { diff --git a/packages/cli-kit/src/private/node/ui/components/LoadingBar.test.tsx b/packages/cli-kit/src/private/node/ui/components/LoadingBar.test.tsx index 308871afbf4..e4ca3078906 100644 --- a/packages/cli-kit/src/private/node/ui/components/LoadingBar.test.tsx +++ b/packages/cli-kit/src/private/node/ui/components/LoadingBar.test.tsx @@ -3,6 +3,7 @@ import {render} from '../../testing/ui.js' import {shouldDisplayColors, unstyled} from '../../../../public/node/output.js' import useLayout from '../hooks/use-layout.js' import React from 'react' + import {beforeEach, describe, expect, test, vi} from 'vitest' vi.mock('../hooks/use-layout.js') diff --git a/packages/cli-kit/src/private/node/ui/components/LoadingBar.tsx b/packages/cli-kit/src/private/node/ui/components/LoadingBar.tsx index db0aa496743..42278012be4 100644 --- a/packages/cli-kit/src/private/node/ui/components/LoadingBar.tsx +++ b/packages/cli-kit/src/private/node/ui/components/LoadingBar.tsx @@ -2,6 +2,7 @@ import {TextAnimation} from './TextAnimation.js' import useLayout from '../hooks/use-layout.js' import {shouldDisplayColors} from '../../../../public/node/output.js' import React from 'react' + import {Box, Text} from 'ink' const loadingBarChar = '▀' diff --git a/packages/cli-kit/src/private/node/ui/components/Prompts/InfoTable.test.tsx b/packages/cli-kit/src/private/node/ui/components/Prompts/InfoTable.test.tsx index eddaf80ecb0..1dde3b4c96e 100644 --- a/packages/cli-kit/src/private/node/ui/components/Prompts/InfoTable.test.tsx +++ b/packages/cli-kit/src/private/node/ui/components/Prompts/InfoTable.test.tsx @@ -2,6 +2,7 @@ import {InfoTable} from './InfoTable.js' import {unstyled} from '../../../../../public/node/output.js' import {render} from '../../../testing/ui.js' import {describe, expect, test} from 'vitest' + import React from 'react' describe('InfoTable', async () => { diff --git a/packages/cli-kit/src/private/node/ui/components/Prompts/InfoTable.tsx b/packages/cli-kit/src/private/node/ui/components/Prompts/InfoTable.tsx index 4670c8cae21..57d79396625 100644 --- a/packages/cli-kit/src/private/node/ui/components/Prompts/InfoTable.tsx +++ b/packages/cli-kit/src/private/node/ui/components/Prompts/InfoTable.tsx @@ -16,11 +16,7 @@ export interface InfoTableSection { } export interface InfoTableProps { - table: - | { - [header: string]: Items - } - | InfoTableSection[] + table: Record | InfoTableSection[] } const InfoTable: FunctionComponent = ({table}) => { @@ -28,7 +24,7 @@ const InfoTable: FunctionComponent = ({table}) => { ? table : Object.keys(table).map((header) => ({ header, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + items: table[header]!, color: undefined, helperText: undefined, diff --git a/packages/cli-kit/src/private/node/ui/components/Prompts/PromptLayout.test.tsx b/packages/cli-kit/src/private/node/ui/components/Prompts/PromptLayout.test.tsx index 8067ce672c2..4b4d685af63 100644 --- a/packages/cli-kit/src/private/node/ui/components/Prompts/PromptLayout.test.tsx +++ b/packages/cli-kit/src/private/node/ui/components/Prompts/PromptLayout.test.tsx @@ -1,6 +1,6 @@ import {PromptLayout} from './PromptLayout.js' -import {render} from '../../../testing/ui.js' import {PromptState} from '../../hooks/use-prompt.js' +import {render} from '../../../testing/ui.js' import {describe, expect, test} from 'vitest' import React from 'react' import {Box, Text} from 'ink' diff --git a/packages/cli-kit/src/private/node/ui/components/Prompts/PromptLayout.tsx b/packages/cli-kit/src/private/node/ui/components/Prompts/PromptLayout.tsx index 740b4bafa6d..c7a461681ff 100644 --- a/packages/cli-kit/src/private/node/ui/components/Prompts/PromptLayout.tsx +++ b/packages/cli-kit/src/private/node/ui/components/Prompts/PromptLayout.tsx @@ -1,11 +1,12 @@ -import {InfoMessage, InfoMessageProps} from './InfoMessage.js' import {InfoTable, InfoTableProps} from './InfoTable.js' +import {InfoMessage, InfoMessageProps} from './InfoMessage.js' import {InlineToken, LinkToken, TokenItem, TokenizedText} from '../TokenizedText.js' import {messageWithPunctuation} from '../../utilities.js' import {AbortSignal} from '../../../../../public/node/abort.js' import useAbortSignal from '../../hooks/use-abort-signal.js' import {PromptState} from '../../hooks/use-prompt.js' import React, {ReactElement, cloneElement, useCallback, useLayoutEffect, useState} from 'react' + import {Box, measureElement, Text, useStdout, DOMElement} from 'ink' import figures from 'figures' diff --git a/packages/cli-kit/src/private/node/ui/components/SelectInput.test.tsx b/packages/cli-kit/src/private/node/ui/components/SelectInput.test.tsx index d4966ea3ee2..e3e2ea17eee 100644 --- a/packages/cli-kit/src/private/node/ui/components/SelectInput.test.tsx +++ b/packages/cli-kit/src/private/node/ui/components/SelectInput.test.tsx @@ -8,6 +8,7 @@ import { } from '../../testing/ui.js' import {platformAndArch} from '../../../../public/node/os.js' import {describe, expect, test, vi} from 'vitest' + import React from 'react' const ARROW_UP = '\u001B[A' diff --git a/packages/cli-kit/src/private/node/ui/components/SelectInput.tsx b/packages/cli-kit/src/private/node/ui/components/SelectInput.tsx index 6155d66ab43..7bbb0cbba0e 100644 --- a/packages/cli-kit/src/private/node/ui/components/SelectInput.tsx +++ b/packages/cli-kit/src/private/node/ui/components/SelectInput.tsx @@ -1,7 +1,7 @@ import {Scrollbar} from './Scrollbar.js' -import {useSelectState} from '../hooks/use-select-state.js' -import useLayout from '../hooks/use-layout.js' import {handleCtrlC} from '../../ui.js' +import useLayout from '../hooks/use-layout.js' +import {useSelectState} from '../hooks/use-select-state.js' import React, {useCallback, forwardRef, useEffect} from 'react' import {Box, Key, useInput, Text, DOMElement} from 'ink' import chalk from 'chalk' @@ -9,9 +9,9 @@ import figures from 'figures' import sortBy from 'lodash/sortBy.js' declare module 'react' { - function forwardRef( - render: (props: P, ref: React.Ref) => React.ReactElement | null, - ): (props: P & React.RefAttributes) => React.ReactElement | null + function forwardRef( + render: (props: TProps, ref: React.Ref) => React.ReactElement | null, + ): (props: TProps & React.RefAttributes) => React.ReactElement | null } export interface SelectInputProps { items: Item[] @@ -80,7 +80,6 @@ interface ItemProps { index: number } -// eslint-disable-next-line react/function-component-definition function Item({ item, previousItem, @@ -132,7 +131,6 @@ function Item({ const MAX_AVAILABLE_LINES = 25 -// eslint-disable-next-line react/function-component-definition function SelectInputInner( { items: rawItems, diff --git a/packages/cli-kit/src/private/node/ui/components/SelectPrompt.test.tsx b/packages/cli-kit/src/private/node/ui/components/SelectPrompt.test.tsx index d553ee40e7b..0bbbf45ad07 100644 --- a/packages/cli-kit/src/private/node/ui/components/SelectPrompt.test.tsx +++ b/packages/cli-kit/src/private/node/ui/components/SelectPrompt.test.tsx @@ -4,6 +4,7 @@ import {unstyled} from '../../../../public/node/output.js' import {Stdout} from '../../ui.js' import {AbortController} from '../../../../public/node/abort.js' import {beforeEach, describe, expect, test, vi} from 'vitest' + import React from 'react' import {useStdout} from 'ink' diff --git a/packages/cli-kit/src/private/node/ui/components/SelectPrompt.tsx b/packages/cli-kit/src/private/node/ui/components/SelectPrompt.tsx index bbaf35d2ae2..8e1606efb37 100644 --- a/packages/cli-kit/src/private/node/ui/components/SelectPrompt.tsx +++ b/packages/cli-kit/src/private/node/ui/components/SelectPrompt.tsx @@ -4,6 +4,7 @@ import {InfoMessageProps} from './Prompts/InfoMessage.js' import {Message, PromptLayout} from './Prompts/PromptLayout.js' import {AbortSignal} from '../../../../public/node/abort.js' import usePrompt, {PromptState} from '../hooks/use-prompt.js' + import React, {ReactElement, useCallback, useEffect} from 'react' import {useApp} from 'ink' @@ -18,7 +19,6 @@ export interface SelectPromptProps { groupOrder?: string[] } -// eslint-disable-next-line react/function-component-definition function SelectPrompt({ message, choices, diff --git a/packages/cli-kit/src/private/node/ui/components/SingleTask.test.tsx b/packages/cli-kit/src/private/node/ui/components/SingleTask.test.tsx index 89c95f0c1f0..d3d159d0b2e 100644 --- a/packages/cli-kit/src/private/node/ui/components/SingleTask.test.tsx +++ b/packages/cli-kit/src/private/node/ui/components/SingleTask.test.tsx @@ -2,6 +2,7 @@ import {SingleTask} from './SingleTask.js' import {render} from '../../testing/ui.js' import {TokenizedString} from '../../../../public/node/output.js' import React from 'react' + import {describe, expect, test} from 'vitest' describe('SingleTask', () => { @@ -170,7 +171,10 @@ describe('SingleTask', () => { test('preserves error types and messages', async () => { // Test with custom error class CustomError extends Error { - constructor(message: string, public code: string) { + constructor( + message: string, + public code: string, + ) { super(message) this.name = 'CustomError' } diff --git a/packages/cli-kit/src/private/node/ui/components/SingleTask.tsx b/packages/cli-kit/src/private/node/ui/components/SingleTask.tsx index 563f4f4001e..a58113df20f 100644 --- a/packages/cli-kit/src/private/node/ui/components/SingleTask.tsx +++ b/packages/cli-kit/src/private/node/ui/components/SingleTask.tsx @@ -2,6 +2,7 @@ import {LoadingBar} from './LoadingBar.js' import {handleCtrlC} from '../../ui.js' import {TokenizedString} from '../../../../public/node/output.js' import React, {useEffect, useState} from 'react' + import {useApp, useInput, useStdin} from 'ink' interface SingleTaskProps { diff --git a/packages/cli-kit/src/private/node/ui/components/Table/ScalarDict.ts b/packages/cli-kit/src/private/node/ui/components/Table/ScalarDict.ts index 5844049b14c..3c96dc37674 100644 --- a/packages/cli-kit/src/private/node/ui/components/Table/ScalarDict.ts +++ b/packages/cli-kit/src/private/node/ui/components/Table/ScalarDict.ts @@ -1,5 +1,4 @@ type Scalar = string | number | boolean | null | undefined -export default interface ScalarDict { - [key: string]: Scalar -} +type ScalarDict = Record +export default ScalarDict diff --git a/packages/cli-kit/src/private/node/ui/components/Table/Table.test.tsx b/packages/cli-kit/src/private/node/ui/components/Table/Table.test.tsx index 5ebdca30e2b..4d3f395291d 100644 --- a/packages/cli-kit/src/private/node/ui/components/Table/Table.test.tsx +++ b/packages/cli-kit/src/private/node/ui/components/Table/Table.test.tsx @@ -17,7 +17,7 @@ describe('Table', async () => { }, ] const color = 'grey' - const columns: TableColumn<{[key in 'name' | 'role' | 'id']: string}> = { + const columns: TableColumn> = { name: {}, role: { color, diff --git a/packages/cli-kit/src/private/node/ui/components/Table/Table.tsx b/packages/cli-kit/src/private/node/ui/components/Table/Table.tsx index 175cfb4d9ad..fed66801d59 100644 --- a/packages/cli-kit/src/private/node/ui/components/Table/Table.tsx +++ b/packages/cli-kit/src/private/node/ui/components/Table/Table.tsx @@ -1,5 +1,5 @@ -import ScalarDict from './ScalarDict.js' import {Row} from './Row.js' +import ScalarDict from './ScalarDict.js' import {unstyled} from '../../../../../public/node/output.js' import React from 'react' import {Box} from 'ink' @@ -14,7 +14,6 @@ export interface TableProps { columns: TableColumn } -// eslint-disable-next-line react/function-component-definition function Table({rows, columns: columnsConfiguration}: TableProps) { const columns = Object.entries(columnsConfiguration).map(([key, {header, color}]) => { const headerWidth = String(header || key).length diff --git a/packages/cli-kit/src/private/node/ui/components/Tasks.test.tsx b/packages/cli-kit/src/private/node/ui/components/Tasks.test.tsx index ab192ca1a45..f7afdec0984 100644 --- a/packages/cli-kit/src/private/node/ui/components/Tasks.test.tsx +++ b/packages/cli-kit/src/private/node/ui/components/Tasks.test.tsx @@ -4,6 +4,7 @@ import {unstyled, TokenizedString} from '../../../../public/node/output.js' import {AbortController} from '../../../../public/node/abort.js' import {Stdout} from '../../ui.js' import React from 'react' + import {beforeEach, describe, expect, test, vi} from 'vitest' import {useStdout} from 'ink' diff --git a/packages/cli-kit/src/private/node/ui/components/Tasks.tsx b/packages/cli-kit/src/private/node/ui/components/Tasks.tsx index cb5153d1793..fd071e06490 100644 --- a/packages/cli-kit/src/private/node/ui/components/Tasks.tsx +++ b/packages/cli-kit/src/private/node/ui/components/Tasks.tsx @@ -5,11 +5,12 @@ import {AbortSignal} from '../../../../public/node/abort.js' import useAbortSignal from '../hooks/use-abort-signal.js' import {useExitOnCtrlC} from '../hooks/use-exit-on-ctrl-c.js' import {TokenizedString} from '../../../../public/node/output.js' + import React, {useRef, useState} from 'react' export interface Task { title: string | TokenizedString - // eslint-disable-next-line @typescript-eslint/no-invalid-void-type + task: (ctx: TContext, task: Task) => Promise[]> retry?: number retryCount?: number @@ -58,7 +59,6 @@ async function runTask(task: Task, ctx: TContext) { const noop = () => {} -// eslint-disable-next-line react/function-component-definition function Tasks({ tasks, silent = isUnitTest(), @@ -67,7 +67,6 @@ function Tasks({ noColor, noProgressBar = false, }: React.PropsWithChildren>) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const [currentTask, setCurrentTask] = useState>(tasks[0]!) const [state, setState] = useState(TasksState.Loading) const ctx = useRef({} as TContext) diff --git a/packages/cli-kit/src/private/node/ui/components/TextAnimation.test.tsx b/packages/cli-kit/src/private/node/ui/components/TextAnimation.test.tsx index 8b2ca4ac910..3593110ae71 100644 --- a/packages/cli-kit/src/private/node/ui/components/TextAnimation.test.tsx +++ b/packages/cli-kit/src/private/node/ui/components/TextAnimation.test.tsx @@ -1,6 +1,6 @@ import {TextAnimation} from './TextAnimation.js' -import {render} from '../../testing/ui.js' import {Stdout} from '../../ui.js' +import {render} from '../../testing/ui.js' import React from 'react' import {beforeEach, describe, expect, test, vi} from 'vitest' import {useStdout} from 'ink' diff --git a/packages/cli-kit/src/private/node/ui/components/TextPrompt.test.tsx b/packages/cli-kit/src/private/node/ui/components/TextPrompt.test.tsx index da4804114e3..80fc4cd5f89 100644 --- a/packages/cli-kit/src/private/node/ui/components/TextPrompt.test.tsx +++ b/packages/cli-kit/src/private/node/ui/components/TextPrompt.test.tsx @@ -4,6 +4,7 @@ import {unstyled} from '../../../../public/node/output.js' import {AbortController} from '../../../../public/node/abort.js' import colors from '../../../../public/node/colors.js' import React from 'react' + import {describe, expect, test, vi} from 'vitest' const ENTER = '\r' diff --git a/packages/cli-kit/src/private/node/ui/components/TextPrompt.tsx b/packages/cli-kit/src/private/node/ui/components/TextPrompt.tsx index a3cb482e38b..d9d94e586da 100644 --- a/packages/cli-kit/src/private/node/ui/components/TextPrompt.tsx +++ b/packages/cli-kit/src/private/node/ui/components/TextPrompt.tsx @@ -1,5 +1,5 @@ -import {TextInput} from './TextInput.js' import {InlineToken, TokenItem, TokenizedText} from './TokenizedText.js' +import {TextInput} from './TextInput.js' import {handleCtrlC} from '../../ui.js' import useLayout from '../hooks/use-layout.js' import {messageWithPunctuation} from '../utilities.js' @@ -7,6 +7,7 @@ import {AbortSignal} from '../../../../public/node/abort.js' import useAbortSignal from '../hooks/use-abort-signal.js' import usePrompt, {PromptState} from '../hooks/use-prompt.js' import React, {FunctionComponent, useCallback, useEffect, useState} from 'react' + import {Box, useApp, useInput, Text} from 'ink' import figures from 'figures' diff --git a/packages/cli-kit/src/private/node/ui/components/TokenizedText.test.tsx b/packages/cli-kit/src/private/node/ui/components/TokenizedText.test.tsx index f0dfefc46e0..16fd76c7002 100644 --- a/packages/cli-kit/src/private/node/ui/components/TokenizedText.test.tsx +++ b/packages/cli-kit/src/private/node/ui/components/TokenizedText.test.tsx @@ -2,6 +2,7 @@ import {tokenItemToString, TokenizedText} from './TokenizedText.js' import {unstyled} from '../../../../public/node/output.js' import {render} from '../../testing/ui.js' import {describe, expect, test} from 'vitest' + import React from 'react' describe('TokenizedText', async () => { diff --git a/packages/cli-kit/src/private/node/ui/components/TokenizedText.tsx b/packages/cli-kit/src/private/node/ui/components/TokenizedText.tsx index 66a7b1928d3..0b4c2bb58e9 100644 --- a/packages/cli-kit/src/private/node/ui/components/TokenizedText.tsx +++ b/packages/cli-kit/src/private/node/ui/components/TokenizedText.tsx @@ -1,12 +1,11 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ import {Command} from './Command.js' import {Link} from './Link.js' import {List} from './List.js' import {UserInput} from './UserInput.js' import {FilePath} from './FilePath.js' import {Subdued} from './Subdued.js' -import {Box, Text} from 'ink' import React, {FunctionComponent} from 'react' +import {Box, Text} from 'ink' export interface LinkToken { link: { diff --git a/packages/cli-kit/src/private/node/ui/contexts/LinksContext.ts b/packages/cli-kit/src/private/node/ui/contexts/LinksContext.ts index 8a1df3ddfb0..efc31d54b6f 100644 --- a/packages/cli-kit/src/private/node/ui/contexts/LinksContext.ts +++ b/packages/cli-kit/src/private/node/ui/contexts/LinksContext.ts @@ -6,7 +6,7 @@ export interface Link { } export interface ContextValue { - links: React.RefObject<{[key: string]: Link}> + links: React.RefObject> addLink: (label: string | undefined, url: string) => string } diff --git a/packages/cli-kit/src/public/common/array.ts b/packages/cli-kit/src/public/common/array.ts index 0eaf56f0d83..8b22c0b7b93 100644 --- a/packages/cli-kit/src/public/common/array.ts +++ b/packages/cli-kit/src/public/common/array.ts @@ -9,7 +9,6 @@ import type {List, ValueIteratee} from 'lodash' * @returns A random element from the array. */ export function takeRandomFromArray(array: T[]): T { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion return array[Math.floor(Math.random() * array.length)]! } diff --git a/packages/cli-kit/src/public/common/collection.ts b/packages/cli-kit/src/public/common/collection.ts index b45baa1deae..f62e25b7f86 100644 --- a/packages/cli-kit/src/public/common/collection.ts +++ b/packages/cli-kit/src/public/common/collection.ts @@ -14,9 +14,7 @@ import type {List, ValueIteratee} from 'lodash' export function groupBy( collection: ArrayLike | null | undefined, iteratee?: ValueIteratee, -): { - [index: string]: T[] -} { +): Record { return lodashGroupBy(collection, iteratee) } diff --git a/packages/cli-kit/src/public/common/object.test.ts b/packages/cli-kit/src/public/common/object.test.ts index e71198c3ed8..93a116639c0 100644 --- a/packages/cli-kit/src/public/common/object.test.ts +++ b/packages/cli-kit/src/public/common/object.test.ts @@ -281,7 +281,7 @@ describe('setPathValue', () => { // Should NOT create a nested structure expect(getPathValue(result, ['key1.with.dots'])).toEqual('value') // Should be accessible as a top-level property - expect((result as {[key: string]: string})['key1.with.dots']).toEqual('value') + expect((result as Record)['key1.with.dots']).toEqual('value') }) test('set nested property under a key that contains dots', () => { diff --git a/packages/cli-kit/src/public/common/string.ts b/packages/cli-kit/src/public/common/string.ts index 89e6bac52eb..0e3e295df4d 100644 --- a/packages/cli-kit/src/public/common/string.ts +++ b/packages/cli-kit/src/public/common/string.ts @@ -1,6 +1,7 @@ import {takeRandomFromArray} from './array.js' -import {unstyled} from '../../public/node/output.js' +import {unstyled} from '../node/output.js' import {Token, TokenItem} from '../../private/node/ui/components/TokenizedText.js' + import {camelCase, capitalCase, constantCase, paramCase, snakeCase, pascalCase} from 'change-case' const SAFE_RANDOM_BUSINESS_ADJECTIVES = [ @@ -212,7 +213,6 @@ export function pluralize< none?: () => TokenItem, ): TokenItem | string { if (items.length === 1) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion return singular(items[0]!) } @@ -253,7 +253,6 @@ export function tryParseInt(maybeInt: string | undefined): number | undefined { export function linesToColumns(lines: string[][]): string { const widths: number[] = [] for (let i = 0; lines[0] && i < lines[0].length; i++) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const columnRows = lines.map((line) => line[i]!) widths.push(Math.max(...columnRows.map((row) => unstyled(row).length))) } @@ -261,7 +260,6 @@ export function linesToColumns(lines: string[][]): string { .map((line) => { return line .map((col, index) => { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion return `${col}${' '.repeat(widths[index]! - unstyled(col).length)}` }) .join(' ') diff --git a/packages/cli-kit/src/public/common/ts/json-narrowing.ts b/packages/cli-kit/src/public/common/ts/json-narrowing.ts index 9f7acd8a377..c2ba1d140e1 100644 --- a/packages/cli-kit/src/public/common/ts/json-narrowing.ts +++ b/packages/cli-kit/src/public/common/ts/json-narrowing.ts @@ -6,7 +6,7 @@ import {BugError} from '../../node/error.js' * @param unknownBlob - The unknown object to validate. * @throws BugError - Thrown if the unknownBlob is not a string map. */ -export function assertStringMap(unknownBlob: unknown): asserts unknownBlob is {[key: string]: string} { +export function assertStringMap(unknownBlob: unknown): asserts unknownBlob is Record { if (typeof unknownBlob !== 'object' || unknownBlob === null) { throw new BugError('Expected an object.') } diff --git a/packages/cli-kit/src/public/node/analytics.test.ts b/packages/cli-kit/src/public/node/analytics.test.ts index 437ee1bb93e..6ca04aa1d4f 100644 --- a/packages/cli-kit/src/public/node/analytics.test.ts +++ b/packages/cli-kit/src/public/node/analytics.test.ts @@ -14,11 +14,12 @@ import {joinPath, dirname} from './path.js' import {publishMonorailEvent} from './monorail.js' import {mockAndCaptureOutput} from './testing/output.js' import {addPublicMetadata} from './metadata.js' -import * as store from '../../private/node/analytics/storage.js' +import {hashString} from './crypto.js' import {startAnalytics} from '../../private/node/analytics.js' -import {hashString} from '../../public/node/crypto.js' +import * as store from '../../private/node/analytics/storage.js' import {CLI_KIT_VERSION} from '../common/version.js' import {setLastSeenAuthMethod, setLastSeenUserIdAfterAuth} from '../../private/node/session.js' + import {test, expect, describe, vi, beforeEach, afterEach, MockedFunction} from 'vitest' vi.mock('./context/local.js') diff --git a/packages/cli-kit/src/public/node/analytics.ts b/packages/cli-kit/src/public/node/analytics.ts index 03345a195be..73cd1b1987f 100644 --- a/packages/cli-kit/src/public/node/analytics.ts +++ b/packages/cli-kit/src/public/node/analytics.ts @@ -2,6 +2,7 @@ import {alwaysLogAnalytics, alwaysLogMetrics, analyticsDisabled, isShopify} from import * as metadata from './metadata.js' import {publishMonorailEvent, MONORAIL_COMMAND_TOPIC} from './monorail.js' import {fanoutHooks} from './plugins.js' +import {outputContent, outputDebug, outputToken} from './output.js' import { recordTiming as storageRecordTiming, recordError as storageRecordError, @@ -10,7 +11,6 @@ import { compileData as storageCompileData, RuntimeData, } from '../../private/node/analytics/storage.js' -import {outputContent, outputDebug, outputToken} from '../../public/node/output.js' import {getEnvironmentData, getSensitiveEnvironmentData} from '../../private/node/analytics.js' import {CLI_KIT_VERSION} from '../common/version.js' import {recordMetrics} from '../../private/node/otel-metrics.js' @@ -18,6 +18,7 @@ import {runWithRateLimit} from '../../private/node/conf-store.js' import {reportingRateLimit} from '../../private/node/constants.js' import {getLastSeenUserIdAfterAuth} from '../../private/node/session.js' import {requestIdsCollection} from '../../private/node/request-ids.js' + import {Interfaces} from '@oclif/core' export type CommandExitMode = diff --git a/packages/cli-kit/src/public/node/api/admin.test.ts b/packages/cli-kit/src/public/node/api/admin.test.ts index f63268f6671..00b4bf7b96e 100644 --- a/packages/cli-kit/src/public/node/api/admin.test.ts +++ b/packages/cli-kit/src/public/node/api/admin.test.ts @@ -2,8 +2,9 @@ import * as admin from './admin.js' import {graphqlRequest, graphqlRequestDoc} from './graphql.js' import {AdminSession} from '../session.js' import {buildHeaders} from '../../../private/node/api/headers.js' -import * as http from '../../../public/node/http.js' +import * as http from '../http.js' import {defaultThemeKitAccessDomain} from '../../../private/node/constants.js' + import {test, vi, expect, describe} from 'vitest' vi.mock('./graphql.js') diff --git a/packages/cli-kit/src/public/node/api/admin.ts b/packages/cli-kit/src/public/node/api/admin.ts index 107d91686fa..68f90d5da7f 100644 --- a/packages/cli-kit/src/public/node/api/admin.ts +++ b/packages/cli-kit/src/public/node/api/admin.ts @@ -6,7 +6,7 @@ import { UnauthorizedHandler, } from './graphql.js' import {AdminSession} from '../session.js' -import {outputContent, outputToken} from '../../../public/node/output.js' +import {outputContent, outputToken} from '../output.js' import {AbortError, BugError} from '../error.js' import { restRequestBody, @@ -17,11 +17,11 @@ import { import {isNetworkError} from '../../../private/node/api.js' import {RequestModeInput, shopifyFetch} from '../http.js' import {PublicApiVersions} from '../../../cli/api/graphql/admin/generated/public_api_versions.js' - import {themeKitAccessDomain} from '../../../private/node/constants.js' import {serviceEnvironment} from '../../../private/node/context/service.js' import {DevServerCore} from '../vendor/dev_server/index.js' import {ClientError, Variables} from 'graphql-request' + import {TypedDocumentNode} from '@graphql-typed-document-node/core' const LatestApiVersionByFQDN = new Map() @@ -108,7 +108,7 @@ export async function adminRequestDoc( return result } -function themeAccessHeaders(session: AdminSession): {[header: string]: string} { +function themeAccessHeaders(session: AdminSession): Record { return isThemeAccessSession(session) ? {'X-Shopify-Shop': session.storeFqdn, 'X-Shopify-Access-Token': session.token} : {} @@ -126,7 +126,7 @@ async function fetchLatestSupportedApiVersion( preferredBehaviour?: RequestModeInput, ): Promise { const apiVersions = await supportedApiVersions(session, preferredBehaviour) - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const latest = apiVersions.reverse()[0]! LatestApiVersionByFQDN.set(session.storeFqdn, latest) return latest @@ -248,7 +248,7 @@ export async function restRequest( path: string, session: AdminSession, requestBody?: T, - searchParams: {[name: string]: string} = {}, + searchParams: Record = {}, apiVersion = 'unstable', ): Promise { const url = restRequestUrl(session, apiVersion, path, searchParams) @@ -289,5 +289,5 @@ export interface RestResponse { /** * HTTP response headers. */ - headers: {[key: string]: string[]} + headers: Record } diff --git a/packages/cli-kit/src/public/node/api/app-dev.ts b/packages/cli-kit/src/public/node/api/app-dev.ts index 8243856cfb4..1bfb899715d 100644 --- a/packages/cli-kit/src/public/node/api/app-dev.ts +++ b/packages/cli-kit/src/public/node/api/app-dev.ts @@ -1,7 +1,7 @@ -import {graphqlRequestDoc, UnauthorizedHandler} from './graphql.js' import {RequestOptions} from './app-management.js' -import {appDevFqdn, normalizeStoreFqdn} from '../context/fqdn.js' +import {graphqlRequestDoc, UnauthorizedHandler} from './graphql.js' import {serviceEnvironment} from '../../../private/node/context/service.js' +import {appDevFqdn, normalizeStoreFqdn} from '../context/fqdn.js' import Bottleneck from 'bottleneck' import {Variables} from 'graphql-request' import {TypedDocumentNode} from '@graphql-typed-document-node/core' diff --git a/packages/cli-kit/src/public/node/api/app-management.test.ts b/packages/cli-kit/src/public/node/api/app-management.test.ts index be5a8951084..9b59a24fe6c 100644 --- a/packages/cli-kit/src/public/node/api/app-management.test.ts +++ b/packages/cli-kit/src/public/node/api/app-management.test.ts @@ -2,6 +2,7 @@ import {appManagementRequestDoc, handleDeprecations} from './app-management.js' import {graphqlRequestDoc, GraphQLResponse} from './graphql.js' import {appManagementFqdn} from '../context/fqdn.js' import {setNextDeprecationDate} from '../../../private/node/context/deprecations-store.js' + import {test, vi, expect, describe, beforeEach, beforeAll} from 'vitest' import {TypedDocumentNode} from '@graphql-typed-document-node/core' diff --git a/packages/cli-kit/src/public/node/api/app-management.ts b/packages/cli-kit/src/public/node/api/app-management.ts index d646895a1b9..1c1e343311a 100644 --- a/packages/cli-kit/src/public/node/api/app-management.ts +++ b/packages/cli-kit/src/public/node/api/app-management.ts @@ -1,10 +1,11 @@ -import {CacheOptions, GraphQLResponse, UnauthorizedHandler, graphqlRequestDoc} from './graphql.js' import {addCursorAndFiltersToAppLogsUrl} from './utilities.js' +import {CacheOptions, GraphQLResponse, UnauthorizedHandler, graphqlRequestDoc} from './graphql.js' import {appManagementFqdn} from '../context/fqdn.js' import {setNextDeprecationDate} from '../../../private/node/context/deprecations-store.js' import {buildHeaders} from '../../../private/node/api/headers.js' import {RequestModeInput} from '../http.js' import Bottleneck from 'bottleneck' + import {TypedDocumentNode} from '@graphql-typed-document-node/core' import {Variables} from 'graphql-request' @@ -28,7 +29,7 @@ async function setupRequest(token: string) { } } -export const appManagementHeaders = (token: string): {[key: string]: string} => { +export const appManagementHeaders = (token: string): Record => { return buildHeaders(token) } diff --git a/packages/cli-kit/src/public/node/api/business-platform.ts b/packages/cli-kit/src/public/node/api/business-platform.ts index e35409f46d7..dcca1af22df 100644 --- a/packages/cli-kit/src/public/node/api/business-platform.ts +++ b/packages/cli-kit/src/public/node/api/business-platform.ts @@ -119,8 +119,10 @@ export async function businessPlatformOrganizationsRequest( }) } -export interface BusinessPlatformOrganizationsRequestOptions - extends BusinessPlatformRequestOptions { +export interface BusinessPlatformOrganizationsRequestOptions< + TResult, + TVariables extends Variables, +> extends BusinessPlatformRequestOptions { organizationId: string } diff --git a/packages/cli-kit/src/public/node/api/functions.ts b/packages/cli-kit/src/public/node/api/functions.ts index aed8c0946fd..568196e985a 100644 --- a/packages/cli-kit/src/public/node/api/functions.ts +++ b/packages/cli-kit/src/public/node/api/functions.ts @@ -1,5 +1,5 @@ -import {graphqlRequestDoc, UnauthorizedHandler} from './graphql.js' import {handleDeprecations} from './app-management.js' +import {graphqlRequestDoc, UnauthorizedHandler} from './graphql.js' import {appManagementFqdn} from '../context/fqdn.js' import {TypedDocumentNode} from '@graphql-typed-document-node/core' import {Variables} from 'graphql-request' diff --git a/packages/cli-kit/src/public/node/api/graphql.test.ts b/packages/cli-kit/src/public/node/api/graphql.test.ts index 619719a26e4..d0a4bf322b4 100644 --- a/packages/cli-kit/src/public/node/api/graphql.test.ts +++ b/packages/cli-kit/src/public/node/api/graphql.test.ts @@ -11,6 +11,7 @@ import {nonRandomUUID} from '../crypto.js' import {CLI_KIT_VERSION} from '../../common/version.js' import * as system from '../system.js' import {test, vi, describe, expect, beforeEach, beforeAll, afterAll, afterEach} from 'vitest' + import {TypedDocumentNode} from '@graphql-typed-document-node/core' import {setupServer} from 'msw/node' import {graphql, HttpResponse} from 'msw' diff --git a/packages/cli-kit/src/public/node/api/graphql.ts b/packages/cli-kit/src/public/node/api/graphql.ts index ad1ca5a28cc..e39f7386062 100644 --- a/packages/cli-kit/src/public/node/api/graphql.ts +++ b/packages/cli-kit/src/public/node/api/graphql.ts @@ -27,12 +27,11 @@ import { import {TypedDocumentNode} from '@graphql-typed-document-node/core' // to replace TVariable type when there graphql query has no variables -export type Exact = {[K in keyof T]: T[K]} +export type Exact> = {[K in keyof T]: T[K]} -export interface GraphQLVariables { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - [key: string]: any -} +// Using a more permissive type to allow generated GraphQL variable interfaces +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type GraphQLVariables = Record export type GraphQLResponse = Awaited>> @@ -57,7 +56,7 @@ interface GraphQLRequestBaseOptions { api: string url: string token?: string - addedHeaders?: {[header: string]: string} + addedHeaders?: Record responseOptions?: GraphQLResponseOptions cacheOptions?: CacheOptions preferredBehaviour?: RequestModeInput @@ -77,7 +76,7 @@ export type GraphQLRequestOptions = GraphQLRequestBaseOptions & { } export type GraphQLRequestDocOptions = GraphQLRequestBaseOptions & { - query: TypedDocumentNode | TypedDocumentNode> + query: TypedDocumentNode | TypedDocumentNode>> variables?: TVariables unauthorizedHandler?: UnauthorizedHandler autoRateLimitRestore?: boolean @@ -109,7 +108,7 @@ async function createGraphQLClient({ }: { url: string token: string | undefined - addedHeaders?: {[header: string]: string} + addedHeaders?: Record }) { const headers = { ...addedHeaders, diff --git a/packages/cli-kit/src/public/node/api/partners.test.ts b/packages/cli-kit/src/public/node/api/partners.test.ts index d287b4d4539..8318224a55f 100644 --- a/packages/cli-kit/src/public/node/api/partners.test.ts +++ b/packages/cli-kit/src/public/node/api/partners.test.ts @@ -4,6 +4,7 @@ import {partnersFqdn} from '../context/fqdn.js' import {blockPartnersAccess} from '../environment.js' import {BugError} from '../error.js' import {setNextDeprecationDate} from '../../../private/node/context/deprecations-store.js' + import {test, vi, expect, describe, beforeEach, beforeAll} from 'vitest' vi.mock('./graphql.js') diff --git a/packages/cli-kit/src/public/node/api/partners.ts b/packages/cli-kit/src/public/node/api/partners.ts index 82903a392cf..87d76ea8e24 100644 --- a/packages/cli-kit/src/public/node/api/partners.ts +++ b/packages/cli-kit/src/public/node/api/partners.ts @@ -1,3 +1,4 @@ +import {addCursorAndFiltersToAppLogsUrl} from './utilities.js' import { graphqlRequest, GraphQLVariables, @@ -6,7 +7,6 @@ import { CacheOptions, UnauthorizedHandler, } from './graphql.js' -import {addCursorAndFiltersToAppLogsUrl} from './utilities.js' import {partnersFqdn} from '../context/fqdn.js' import {setNextDeprecationDate} from '../../../private/node/context/deprecations-store.js' import {getPackageManager} from '../node-package-manager.js' @@ -16,6 +16,7 @@ import {formatPackageManagerCommand} from '../output.js' import {RequestModeInput} from '../http.js' import {blockPartnersAccess} from '../environment.js' import Bottleneck from 'bottleneck' + import {Variables} from 'graphql-request' import {TypedDocumentNode} from '@graphql-typed-document-node/core' diff --git a/packages/cli-kit/src/public/node/api/rest-api-throttler.ts b/packages/cli-kit/src/public/node/api/rest-api-throttler.ts index 0902e332dc2..2029cf952c7 100644 --- a/packages/cli-kit/src/public/node/api/rest-api-throttler.ts +++ b/packages/cli-kit/src/public/node/api/rest-api-throttler.ts @@ -142,9 +142,7 @@ interface ThrottlingState { } } -const _throttlingState: { - [context: string]: ThrottlingState -} = {} +const _throttlingState: Record = {} function extractRetryDelayMsFromResponse(response: RestResponse): number { const retryAfterStr = header(response, 'retry-after') @@ -275,7 +273,7 @@ if (import.meta.vitest) { // When const callLimit = extractApiCallLimitFromResponse(response) - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const [used, limit] = callLimit! // Then diff --git a/packages/cli-kit/src/public/node/archiver.integration.test.ts b/packages/cli-kit/src/public/node/archiver.integration.test.ts index cab877fc2e5..989609b9e16 100644 --- a/packages/cli-kit/src/public/node/archiver.integration.test.ts +++ b/packages/cli-kit/src/public/node/archiver.integration.test.ts @@ -5,6 +5,7 @@ import {exec} from './system.js' import {describe, expect, test} from 'vitest' import StreamZip from 'node-stream-zip' import brotli from 'brotli' + import fs from 'fs' describe('zip', () => { @@ -154,7 +155,7 @@ async function createFiles(structure: string[], directory: string) { async function readArchiveFiles(zipPath: string) { await expect(fileExists(zipPath)).resolves.toBeTruthy() - // eslint-disable-next-line @babel/new-cap + // eslint-disable-next-line new-cap const archive = new StreamZip.async({file: zipPath}) const archiveEntries = Object.keys(await archive.entries()) await archive.close() diff --git a/packages/cli-kit/src/public/node/archiver.ts b/packages/cli-kit/src/public/node/archiver.ts index dda288526aa..1223c08af04 100644 --- a/packages/cli-kit/src/public/node/archiver.ts +++ b/packages/cli-kit/src/public/node/archiver.ts @@ -1,6 +1,6 @@ -import {relativePath, joinPath, dirname} from './path.js' +import {outputDebug, outputContent, outputToken} from './output.js' import {glob, removeFile} from './fs.js' -import {outputDebug, outputContent, outputToken} from '../../public/node/output.js' +import {relativePath, joinPath, dirname} from './path.js' import archiver from 'archiver' import {createWriteStream, readFileSync, writeFileSync} from 'fs' import {readFile} from 'fs/promises' diff --git a/packages/cli-kit/src/public/node/base-command.test.ts b/packages/cli-kit/src/public/node/base-command.test.ts index 2ff22d7801c..63c0a0fd19a 100644 --- a/packages/cli-kit/src/public/node/base-command.test.ts +++ b/packages/cli-kit/src/public/node/base-command.test.ts @@ -17,7 +17,7 @@ beforeEach(() => { vi.unstubAllEnvs() }) -let testResult: {[flag: string]: unknown} = {} +let testResult: Record = {} let testError: Error | undefined class MockCommand extends Command { diff --git a/packages/cli-kit/src/public/node/base-command.ts b/packages/cli-kit/src/public/node/base-command.ts index f4236e53e94..e5b5f8398c8 100644 --- a/packages/cli-kit/src/public/node/base-command.ts +++ b/packages/cli-kit/src/public/node/base-command.ts @@ -12,6 +12,7 @@ import {showNotificationsIfNeeded} from './notifications-system.js' import {setCurrentCommandId} from './global-context.js' import {JsonMap} from '../../private/common/json.js' import {underscore} from '../common/string.js' + import {Command, Config, Errors} from '@oclif/core' import {OutputFlags, Input, ParserOutput, FlagInput, OutputArgs} from '@oclif/core/parser' @@ -26,7 +27,6 @@ interface EnvironmentFlags { } abstract class BaseCommand extends Command { - // eslint-disable-next-line @typescript-eslint/ban-types static baseFlags: FlagInput<{}> = {} // Replace markdown links to plain text like: "link label" (url) @@ -82,7 +82,6 @@ abstract class BaseCommand extends Command { } } - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types protected exitWithTimestampWhenEnvVariablePresent() { if (isTruthy(process.env.SHOPIFY_CLI_ENV_STARTUP_PERFORMANCE_RUN)) { outputResult(` diff --git a/packages/cli-kit/src/public/node/cli.ts b/packages/cli-kit/src/public/node/cli.ts index e047e11421e..a9aa86af88d 100644 --- a/packages/cli-kit/src/public/node/cli.ts +++ b/packages/cli-kit/src/public/node/cli.ts @@ -2,6 +2,7 @@ import {isTruthy} from './context/utilities.js' import {launchCLI as defaultLaunchCli} from './cli-launcher.js' import {cacheClear} from '../../private/node/conf-store.js' import {environmentVariables} from '../../private/node/constants.js' + import {Flags} from '@oclif/core' /** diff --git a/packages/cli-kit/src/public/node/context/local.test.ts b/packages/cli-kit/src/public/node/context/local.test.ts index 476cd734d5d..10c4a37f07c 100644 --- a/packages/cli-kit/src/public/node/context/local.test.ts +++ b/packages/cli-kit/src/public/node/context/local.test.ts @@ -12,6 +12,7 @@ import { } from './local.js' import {fileExists} from '../fs.js' import {exec} from '../system.js' + import {expect, describe, vi, test} from 'vitest' vi.mock('../fs.js') diff --git a/packages/cli-kit/src/public/node/context/local.ts b/packages/cli-kit/src/public/node/context/local.ts index ce1afcffc57..4da6fa56320 100644 --- a/packages/cli-kit/src/public/node/context/local.ts +++ b/packages/cli-kit/src/public/node/context/local.ts @@ -3,8 +3,10 @@ import {getCIMetadata, isSet, Metadata} from '../../../private/node/context/util import {defaultThemeKitAccessDomain, environmentVariables, pathConstants} from '../../../private/node/constants.js' import {fileExists} from '../fs.js' import {exec} from '../system.js' + import isInteractive from 'is-interactive' import macaddress from 'macaddress' + import {homedir} from 'os' /** diff --git a/packages/cli-kit/src/public/node/custom-oclif-loader.ts b/packages/cli-kit/src/public/node/custom-oclif-loader.ts index 750eb999ec1..527f837eabb 100644 --- a/packages/cli-kit/src/public/node/custom-oclif-loader.ts +++ b/packages/cli-kit/src/public/node/custom-oclif-loader.ts @@ -32,7 +32,7 @@ export class ShopifyConfig extends Config { if (isDevelopment()) { // @ts-expect-error: This is a private method that we are overriding. OCLIF doesn't provide a way to extend it. - // eslint-disable-next-line @typescript-eslint/unbound-method + this.determinePriority = this.customPriority } } diff --git a/packages/cli-kit/src/public/node/dot-env.ts b/packages/cli-kit/src/public/node/dot-env.ts index 9f22b17904b..1c2e4cff31c 100644 --- a/packages/cli-kit/src/public/node/dot-env.ts +++ b/packages/cli-kit/src/public/node/dot-env.ts @@ -1,7 +1,6 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import {outputDebug, outputContent, outputToken} from './output.js' import {AbortError} from './error.js' import {fileExists, readFile, writeFile} from './fs.js' -import {outputDebug, outputContent, outputToken} from '../../public/node/output.js' import {parse} from 'dotenv' /** @@ -15,7 +14,7 @@ export interface DotEnvFile { /** * Variables of the .env file. */ - variables: {[name: string]: string} + variables: Record } /** @@ -53,10 +52,7 @@ export async function writeDotEnv(file: DotEnvFile): Promise { * @param envFileContent - .env file contents. * @param updatedValues - object containing new env variables values. */ -export function patchEnvFile( - envFileContent: string | null, - updatedValues: {[key: string]: string | undefined}, -): string { +export function patchEnvFile(envFileContent: string | null, updatedValues: Record): string { const outputLines: string[] = [] const envFileLines = envFileContent === null ? [] : envFileContent.split('\n') diff --git a/packages/cli-kit/src/public/node/environments.ts b/packages/cli-kit/src/public/node/environments.ts index 2555f7cc775..cdbf3c8075d 100644 --- a/packages/cli-kit/src/public/node/environments.ts +++ b/packages/cli-kit/src/public/node/environments.ts @@ -5,9 +5,7 @@ import * as metadata from './metadata.js' import {renderWarning} from './ui.js' import {JsonMap} from '../../private/common/json.js' -export interface Environments { - [name: string]: JsonMap -} +export type Environments = Record interface LoadEnvironmentOptions { from?: string diff --git a/packages/cli-kit/src/public/node/error-handler.test.ts b/packages/cli-kit/src/public/node/error-handler.test.ts index 490cb631ea2..c17d7f0472c 100644 --- a/packages/cli-kit/src/public/node/error-handler.test.ts +++ b/packages/cli-kit/src/public/node/error-handler.test.ts @@ -3,9 +3,10 @@ import * as metadata from './metadata.js' import {ciPlatform, cloudEnvironment, isUnitTest, macAddress} from './context/local.js' import {mockAndCaptureOutput} from './testing/output.js' import * as error from './error.js' -import {hashString} from '../../public/node/crypto.js' +import {hashString} from './crypto.js' import {isLocalEnvironment} from '../../private/node/context/service.js' import {getLastSeenUserIdAfterAuth} from '../../private/node/session.js' + import {settings} from '@oclif/core' import {beforeEach, describe, expect, test, vi} from 'vitest' diff --git a/packages/cli-kit/src/public/node/error-handler.ts b/packages/cli-kit/src/public/node/error-handler.ts index 29803ec26ca..ceb1d576ceb 100644 --- a/packages/cli-kit/src/public/node/error-handler.ts +++ b/packages/cli-kit/src/public/node/error-handler.ts @@ -10,16 +10,18 @@ import { handler, cleanSingleStackTracePath, } from './error.js' -import {isLocalEnvironment} from '../../private/node/context/service.js' +import {outputDebug, outputInfo} from './output.js' import {getEnvironmentData} from '../../private/node/analytics.js' -import {outputDebug, outputInfo} from '../../public/node/output.js' +import {isLocalEnvironment} from '../../private/node/context/service.js' import {bugsnagApiKey, reportingRateLimit} from '../../private/node/constants.js' import {CLI_KIT_VERSION} from '../common/version.js' import {runWithRateLimit} from '../../private/node/conf-store.js' import {getLastSeenUserIdAfterAuth} from '../../private/node/session.js' + import {settings, Interfaces} from '@oclif/core' import StackTracey from 'stacktracey' import Bugsnag, {Event} from '@bugsnag/js' + import {realpath} from 'fs/promises' // Allowed slice names for error analytics grouping. @@ -232,7 +234,7 @@ export async function registerCleanBugsnagErrorsFromWithinPlugins(config: Interf }) } -// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any +// eslint-disable-next-line @typescript-eslint/no-explicit-any export async function addBugsnagMetadata(event: any, config: Interfaces.Config): Promise { const publicData = metadata.getAllPublicMetadata() const {commandStartOptions} = metadata.getAllSensitiveMetadata() @@ -250,10 +252,10 @@ export async function addBugsnagMetadata(event: any, config: Interfaces.Config): pluginData: otherPluginsPublic, } - const appData = {} as {[key: string]: unknown} - const commandData = {} as {[key: string]: unknown} - const environmentData = {} as {[key: string]: unknown} - const miscData = {} as {[key: string]: unknown} + const appData = {} as Record + const commandData = {} as Record + const environmentData = {} as Record + const miscData = {} as Record const appKeys = ['api_key', 'business_platform_id', 'partner_id', 'project_type'] const commandKeys = ['command'] const environmentKeys = ['cli_version', 'node_version', 'uname'] diff --git a/packages/cli-kit/src/public/node/error.ts b/packages/cli-kit/src/public/node/error.ts index c8ada6f48e8..2de5c3e3e4e 100644 --- a/packages/cli-kit/src/public/node/error.ts +++ b/packages/cli-kit/src/public/node/error.ts @@ -1,7 +1,8 @@ import {AlertCustomSection, renderFatalError} from './ui.js' -import {OutputMessage, stringifyMessage, TokenizedString} from '../../public/node/output.js' -import {normalizePath} from '../../public/node/path.js' +import {normalizePath} from './path.js' +import {OutputMessage, stringifyMessage, TokenizedString} from './output.js' import {InlineToken, TokenItem, tokenItemToString} from '../../private/node/ui/components/TokenizedText.js' + import {Errors} from '@oclif/core' export {ExtendableError} from 'ts-error' diff --git a/packages/cli-kit/src/public/node/framework.ts b/packages/cli-kit/src/public/node/framework.ts index b5e6f643813..0c483c165df 100644 --- a/packages/cli-kit/src/public/node/framework.ts +++ b/packages/cli-kit/src/public/node/framework.ts @@ -149,7 +149,7 @@ const frameworks: Framework[] = [ * @returns The name of the framework used or 'unknown' otherwise */ export async function resolveFramework(rootDirectory: string): Promise { - const fwConfigFiles: {[key: string]: string | undefined} = {} + const fwConfigFiles: Record = {} const matchedFramework = frameworks.find( (framework) => @@ -172,17 +172,16 @@ export async function resolveFramework(rootDirectory: string): Promise { return matchedFramework ? matchedFramework.name : 'unknown' } -function matchDetector(detector: FrameworkDetectionPattern, fwConfigFiles: {[key: string]: string | undefined} = {}) { +function matchDetector(detector: FrameworkDetectionPattern, fwConfigFiles: Record = {}) { if (!fwConfigFiles[detector.path]) return false - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion return !detector.matchContent || new RegExp(detector.matchContent).test(fwConfigFiles[detector.path]!) } function loadFwConfigFile( rootPath: string, fwConfigFileName: string, - fwConfigFiles: {[key: string]: string | undefined} = {}, + fwConfigFiles: Record = {}, ) { if (fwConfigFiles[fwConfigFileName]) { return fwConfigFiles diff --git a/packages/cli-kit/src/public/node/fs.test.ts b/packages/cli-kit/src/public/node/fs.test.ts index 4041facc5ef..60a3a973541 100644 --- a/packages/cli-kit/src/public/node/fs.test.ts +++ b/packages/cli-kit/src/public/node/fs.test.ts @@ -27,6 +27,7 @@ import {joinPath, normalizePath} from './path.js' import {takeRandomFromArray} from '../common/array.js' import {beforeEach, describe, expect, test, vi} from 'vitest' import FastGlob from 'fast-glob' + import * as os from 'os' vi.mock('../common/array.js') diff --git a/packages/cli-kit/src/public/node/fs.ts b/packages/cli-kit/src/public/node/fs.ts index 09c16a4ce35..31d5c080f1c 100644 --- a/packages/cli-kit/src/public/node/fs.ts +++ b/packages/cli-kit/src/public/node/fs.ts @@ -1,7 +1,7 @@ +import {outputContent, outputToken, outputDebug} from './output.js' import {joinPath, normalizePath} from './path.js' -import {outputContent, outputToken, outputDebug} from '../../public/node/output.js' -import {getRandomName, RandomNameFamily} from '../common/string.js' import {OverloadParameters} from '../../private/common/ts/overloaded-parameters.js' +import {getRandomName, RandomNameFamily} from '../common/string.js' import { copy as fsCopy, ensureFile as fsEnsureFile, @@ -34,6 +34,7 @@ import { WriteStream, statSync, } from 'fs' + import { mkdir as fsMkdir, writeFile as fsWriteFile, @@ -52,6 +53,7 @@ import { } from 'fs/promises' import {pathToFileURL as pathToFile} from 'url' import * as os from 'os' + import type {Pattern, Options as GlobOptions} from 'fast-glob' /** diff --git a/packages/cli-kit/src/public/node/git.ts b/packages/cli-kit/src/public/node/git.ts index e095aa01150..d79bee025b0 100644 --- a/packages/cli-kit/src/public/node/git.ts +++ b/packages/cli-kit/src/public/node/git.ts @@ -1,4 +1,4 @@ -/* eslint-disable @typescript-eslint/no-base-to-string */ +import {outputContent, outputToken, outputDebug} from './output.js' import {hasGit, isTerminalInteractive} from './context/local.js' import { appendFileSync, @@ -13,8 +13,8 @@ import { import {AbortError} from './error.js' import {cwd, joinPath} from './path.js' import {runWithTimer} from './metadata.js' -import {outputContent, outputToken, outputDebug} from '../../public/node/output.js' import git, {TaskOptions, SimpleGitProgressEvent, DefaultLogFields, ListLogLine, SimpleGit} from 'simple-git' + import ignore from 'ignore' /** @@ -46,9 +46,7 @@ export async function checkIfIgnoredInGitRepository(directory: string, files: st return withGit({directory}, (repo) => repo.checkIgnore(files)) } -export interface GitIgnoreTemplate { - [section: string]: string[] -} +export type GitIgnoreTemplate = Record /** * Create a .gitignore file in the given directory. * @@ -190,7 +188,7 @@ export async function downloadGitRepository(cloneOptions: GitCloneOptions): Prom try { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + await git(simpleGitOptions).clone(repository!, destination, options) if (latestTag) { diff --git a/packages/cli-kit/src/public/node/github.ts b/packages/cli-kit/src/public/node/github.ts index 9214dafd754..c174e763c44 100644 --- a/packages/cli-kit/src/public/node/github.ts +++ b/packages/cli-kit/src/public/node/github.ts @@ -1,11 +1,10 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ +import {outputContent, outputDebug, outputToken} from './output.js' import {err, ok, Result} from './result.js' import {fetch, Response} from './http.js' import {writeFile, mkdir, inTemporaryDirectory, moveFile, chmod} from './fs.js' import {dirname, joinPath} from './path.js' import {runWithTimer} from './metadata.js' import {AbortError} from './error.js' -import {outputContent, outputDebug, outputToken} from '../../public/node/output.js' class GitHubClientError extends Error { // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -94,7 +93,7 @@ export function parseGitHubRepositoryURL(url: string): Result)} `) } diff --git a/packages/cli-kit/src/public/node/json-schema.ts b/packages/cli-kit/src/public/node/json-schema.ts index e22f71e8d86..e5cb6b2ec9f 100644 --- a/packages/cli-kit/src/public/node/json-schema.ts +++ b/packages/cli-kit/src/public/node/json-schema.ts @@ -1,7 +1,7 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ -import {ParseConfigurationResult} from './schema.js' import {randomUUID} from './crypto.js' +import {ParseConfigurationResult} from './schema.js' import {getPathValue} from '../common/object.js' + import {capitalize} from '../common/string.js' import {Ajv, ErrorObject, SchemaObject, ValidateFunction} from 'ajv' import $RefParser from '@apidevtools/json-schema-ref-parser' @@ -9,7 +9,7 @@ import cloneDeep from 'lodash/cloneDeep.js' export type HandleInvalidAdditionalProperties = 'strip' | 'fail' -type AjvError = ErrorObject +type AjvError = ErrorObject> /** * Normalises a JSON Schema by standardising it's internal implementation. @@ -90,7 +90,7 @@ export function jsonSchemaValidate( Object.keys(subjectToModify).forEach((key) => { if (!topLevelSchemaProperties.includes(key)) { // this isn't actually dynamic, because key came from Object.keys - // eslint-disable-next-line @typescript-eslint/no-dynamic-delete + delete subjectToModify[key as keyof typeof subjectToModify] } }) diff --git a/packages/cli-kit/src/public/node/liquid.ts b/packages/cli-kit/src/public/node/liquid.ts index 95640c0a442..47cdb18ff27 100644 --- a/packages/cli-kit/src/public/node/liquid.ts +++ b/packages/cli-kit/src/public/node/liquid.ts @@ -11,7 +11,7 @@ import { matchGlob, } from './fs.js' import {joinPath, dirname, relativePath} from './path.js' -import {outputContent, outputToken, outputDebug} from '../../public/node/output.js' +import {outputContent, outputToken, outputDebug} from './output.js' import {Liquid} from 'liquidjs' /** diff --git a/packages/cli-kit/src/public/node/local-storage.test.ts b/packages/cli-kit/src/public/node/local-storage.test.ts index 9d786b8c344..b50b5db7fc2 100644 --- a/packages/cli-kit/src/public/node/local-storage.test.ts +++ b/packages/cli-kit/src/public/node/local-storage.test.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/dot-notation */ import {LocalStorage} from './local-storage.js' import {inTemporaryDirectory} from './fs.js' import {AbortError} from './error.js' @@ -9,6 +8,13 @@ interface TestSchema { testValue: string } +// Helper to access private config for testing +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function getConfig(storage: LocalStorage): any { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return (storage as any).config +} + describe('storage', () => { test('set and returns a value', async () => { await inTemporaryDirectory((cwd) => { @@ -71,16 +77,16 @@ describe('error handling', () => { vi.spyOn(fs, 'unixFileIsOwnedByCurrentUser').mockReturnValue(true) // Mock Config to throw - storage['config'].set = vi.fn(() => { + getConfig(storage).set = vi.fn(() => { throw new Error('EACCES: permission denied') }) - storage['config'].get = vi.fn(() => { + getConfig(storage).get = vi.fn(() => { throw new Error('EACCES: permission denied') }) - storage['config'].delete = vi.fn(() => { + getConfig(storage).delete = vi.fn(() => { throw new Error('EACCES: permission denied') }) - storage['config'].clear = vi.fn(() => { + getConfig(storage).clear = vi.fn(() => { throw new Error('EACCES: permission denied') }) @@ -111,7 +117,7 @@ describe('error handling', () => { // Mock Config to throw - storage['config'].get = vi.fn(() => { + getConfig(storage).get = vi.fn(() => { throw new Error('EACCES: permission denied') }) @@ -143,7 +149,7 @@ describe('error handling', () => { // Mock Config to throw non-permission error - storage['config'].set = vi.fn(() => { + getConfig(storage).set = vi.fn(() => { throw new Error('Invalid JSON format') }) diff --git a/packages/cli-kit/src/public/node/local-storage.ts b/packages/cli-kit/src/public/node/local-storage.ts index de9116d1263..9759267aab9 100644 --- a/packages/cli-kit/src/public/node/local-storage.ts +++ b/packages/cli-kit/src/public/node/local-storage.ts @@ -9,7 +9,7 @@ import Config from 'conf' * for accessing the local storage. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any -export class LocalStorage { +export class LocalStorage> { private readonly config: Config constructor(options: {projectName?: string; cwd?: string}) { diff --git a/packages/cli-kit/src/public/node/metadata.ts b/packages/cli-kit/src/public/node/metadata.ts index 63747f1980c..ae77344aa77 100644 --- a/packages/cli-kit/src/public/node/metadata.ts +++ b/packages/cli-kit/src/public/node/metadata.ts @@ -61,7 +61,7 @@ export type SensitiveSchema = T extends RuntimeMetadataManager, >(defaultPublicMetadata: Partial = {}): RuntimeMetadataManager { const raw: {sensitive: Partial; public: Partial} = { sensitive: {}, @@ -142,7 +142,7 @@ export function createRuntimeMetadataContainer< // The top of the stack is the total time for all nested timers const wallClockDuration = Math.max(end - start, 0) - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const childDurations = durationStack.pop()! const duration = Math.max(wallClockDuration - childDurations, 0) diff --git a/packages/cli-kit/src/public/node/mimes.ts b/packages/cli-kit/src/public/node/mimes.ts index 80f5fd230b8..0cdcdd3e1be 100644 --- a/packages/cli-kit/src/public/node/mimes.ts +++ b/packages/cli-kit/src/public/node/mimes.ts @@ -16,7 +16,7 @@ export function lookupMimeType(fileName: string): string { * * @param newTypes - Object of key-values where key is extension and value is mime type. */ -export function setMimeTypes(newTypes: {[key: string]: string}): void { +export function setMimeTypes(newTypes: Record): void { Object.entries(newTypes).forEach(([extension, mimeType]) => { mimes[extension] = mimeType }) diff --git a/packages/cli-kit/src/public/node/monorail.ts b/packages/cli-kit/src/public/node/monorail.ts index 10f1ecf1b8c..b687ec9fee4 100644 --- a/packages/cli-kit/src/public/node/monorail.ts +++ b/packages/cli-kit/src/public/node/monorail.ts @@ -1,6 +1,6 @@ import {fetch} from './http.js' +import {outputDebug, outputContent, outputToken} from './output.js' import {JsonMap} from '../../private/common/json.js' -import {outputDebug, outputContent, outputToken} from '../../public/node/output.js' import {DeepRequired} from '../common/ts/deep-required.js' export {DeepRequired} diff --git a/packages/cli-kit/src/public/node/multiple-installation-warning.ts b/packages/cli-kit/src/public/node/multiple-installation-warning.ts index 4e6e72e345e..b99fb13c3f2 100644 --- a/packages/cli-kit/src/public/node/multiple-installation-warning.ts +++ b/packages/cli-kit/src/public/node/multiple-installation-warning.ts @@ -14,7 +14,7 @@ import {runAtMinimumInterval} from '../../private/node/conf-store.js' */ export async function showMultipleCLIWarningIfNeeded( directory: string, - dependencies: {[key: string]: string}, + dependencies: Record, ): Promise { // Show the warning only once per day await runAtMinimumInterval('warn-on-multiple-versions', {days: 1}, async () => { diff --git a/packages/cli-kit/src/public/node/node-package-manager.ts b/packages/cli-kit/src/public/node/node-package-manager.ts index 5aa52ef72aa..501f75ee444 100644 --- a/packages/cli-kit/src/public/node/node-package-manager.ts +++ b/packages/cli-kit/src/public/node/node-package-manager.ts @@ -5,12 +5,15 @@ import {fileExists, readFile, writeFile, findPathUp, glob} from './fs.js' import {dirname, joinPath} from './path.js' import {runWithTimer} from './metadata.js' import {inferPackageManagerForGlobalCLI} from './is-global.js' -import {outputToken, outputContent, outputDebug} from '../../public/node/output.js' +import {outputToken, outputContent, outputDebug} from './output.js' import {PackageVersionKey, cacheRetrieve, cacheRetrieveOrRepopulate} from '../../private/node/conf-store.js' import {parseJSON} from '../common/json.js' + import latestVersion from 'latest-version' import {SemVer, satisfies as semverSatisfies} from 'semver' + import type {Writable} from 'stream' + import type {ExecOptions} from './system.js' /** The name of the Yarn lock file */ @@ -30,7 +33,7 @@ export const pnpmWorkspaceFile = 'pnpm-workspace.yaml' /** An array containing the lockfiles from all the package managers */ export const lockfiles: Lockfile[] = [yarnLockfile, pnpmLockfile, npmLockfile, bunLockfile] -export const lockfilesByManager: {[key in PackageManager]: Lockfile | undefined} = { +export const lockfilesByManager: Record = { yarn: yarnLockfile, npm: npmLockfile, pnpm: pnpmLockfile, @@ -241,10 +244,10 @@ export async function getPackageVersion(packageJsonPath: string): Promise { +export async function getDependencies(packageJsonPath: string): Promise> { const packageJsonContent = await readAndParsePackageJson(packageJsonPath) - const dependencies: {[key: string]: string} = packageJsonContent.dependencies ?? {} - const devDependencies: {[key: string]: string} = packageJsonContent.devDependencies ?? {} + const dependencies: Record = packageJsonContent.dependencies ?? {} + const devDependencies: Record = packageJsonContent.devDependencies ?? {} return {...dependencies, ...devDependencies} } @@ -345,22 +348,22 @@ export interface PackageJson { /** * The scripts attribute of the package.json */ - scripts?: {[key: string]: string} + scripts?: Record /** * The dependencies attribute of the package.json */ - dependencies?: {[key: string]: string} + dependencies?: Record /** * The devDependencies attribute of the package.json */ - devDependencies?: {[key: string]: string} + devDependencies?: Record /** * The peerDependencies attribute of the package.json */ - peerDependencies?: {[key: string]: string} + peerDependencies?: Record /** * The optional oclif settings attribute of the package.json @@ -377,12 +380,12 @@ export interface PackageJson { /** * The resolutions attribute of the package.json. Only useful when using yarn as package manager */ - resolutions?: {[key: string]: string} + resolutions?: Record /** * The overrides attribute of the package.json. Only useful when using npm o npmn as package managers */ - overrides?: {[key: string]: string} + overrides?: Record /** * The prettier attribute of the package.json @@ -681,7 +684,7 @@ export async function findUpAndReadPackageJson(fromDirectory: string): Promise<{ } } -export async function addResolutionOrOverride(directory: string, dependencies: {[key: string]: string}): Promise { +export async function addResolutionOrOverride(directory: string, dependencies: Record): Promise { const packageManager = await getPackageManager(directory) const packageJsonPath = joinPath(directory, 'package.json') const packageJsonContent = await readAndParsePackageJson(packageJsonPath) diff --git a/packages/cli-kit/src/public/node/os.ts b/packages/cli-kit/src/public/node/os.ts index a05fbf6e9e7..5c84c96964a 100644 --- a/packages/cli-kit/src/public/node/os.ts +++ b/packages/cli-kit/src/public/node/os.ts @@ -1,4 +1,4 @@ -import {outputDebug, outputContent} from '../../public/node/output.js' +import {outputDebug, outputContent} from './output.js' import {execa} from 'execa' import {userInfo as osUserInfo} from 'os' diff --git a/packages/cli-kit/src/public/node/output.test.ts b/packages/cli-kit/src/public/node/output.test.ts index 8191b361935..f4acf2cfb12 100644 --- a/packages/cli-kit/src/public/node/output.test.ts +++ b/packages/cli-kit/src/public/node/output.test.ts @@ -34,7 +34,7 @@ describe('Output helpers', () => { }) describe('Color disabling', () => { - function processLike({env, stdoutIsTTY}: {env: {[variable: string]: string}; stdoutIsTTY: boolean}) { + function processLike({env, stdoutIsTTY}: {env: Record; stdoutIsTTY: boolean}) { const pseudoProcess = { ...process, env, diff --git a/packages/cli-kit/src/public/node/output.ts b/packages/cli-kit/src/public/node/output.ts index db95c2ebd14..c4384e0d129 100644 --- a/packages/cli-kit/src/public/node/output.ts +++ b/packages/cli-kit/src/public/node/output.ts @@ -21,8 +21,11 @@ import { } from '../../private/node/content-tokens.js' import {tokenItemToString} from '../../private/node/ui/components/TokenizedText.js' import {consoleLog, consoleWarn, output} from '../../private/node/output.js' + import stripAnsi from 'strip-ansi' + import {Writable} from 'stream' + import type {Change} from 'diff' export type Logger = Writable | ((message: string, logLevel?: LogLevel) => void) @@ -148,7 +151,7 @@ export function outputContent( if (i >= keys.length) { return } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const token = keys[i]! if (typeof token === 'string') { @@ -224,8 +227,8 @@ function shouldOutput(logLevel: LogLevel): boolean { return messageLogLevelValue >= currentLogLevelValue } -// eslint-disable-next-line import/no-mutable-exports -export let collectedLogs: {[key: string]: string[]} = {} +// eslint-disable-next-line import-x/no-mutable-exports +export let collectedLogs: Record = {} /** * This is only used during UnitTesting. diff --git a/packages/cli-kit/src/public/node/path.ts b/packages/cli-kit/src/public/node/path.ts index 1b064805c9c..43e63bf3ce3 100644 --- a/packages/cli-kit/src/public/node/path.ts +++ b/packages/cli-kit/src/public/node/path.ts @@ -10,7 +10,7 @@ import { isAbsolute, } from 'pathe' import {fileURLToPath} from 'url' -// eslint-disable-next-line node/prefer-global/url +// eslint-disable-next-line n/prefer-global/url import type {URL} from 'url' /** diff --git a/packages/cli-kit/src/public/node/plugins.ts b/packages/cli-kit/src/public/node/plugins.ts index d8752d2617a..caf1189990b 100644 --- a/packages/cli-kit/src/public/node/plugins.ts +++ b/packages/cli-kit/src/public/node/plugins.ts @@ -3,6 +3,7 @@ import {MonorailEventPublic, MonorailEventSensitive} from './monorail.js' import {getArrayContainsDuplicates, getArrayRejectingUndefined} from '../common/array.js' import {PickByPrefix} from '../common/ts/pick-by-prefix.js' import {JsonMap} from '../../private/common/json.js' + import {Config, Interfaces} from '@oclif/core' /** @@ -40,22 +41,22 @@ type AppSpecificSensitiveMonorailFields = PickByPrefix pluginReturns: { '@shopify/app': Partial [pluginName: string]: JsonMap } } sensitive_command_metadata: { - options: {[key: string]: never} + options: Record pluginReturns: { '@shopify/app': Partial [pluginName: string]: JsonMap } } [hookName: string]: { - options: {[key: string]: unknown} - pluginReturns: {[key: string]: unknown} + options: Record + pluginReturns: Record } } diff --git a/packages/cli-kit/src/public/node/plugins/tunnel.ts b/packages/cli-kit/src/public/node/plugins/tunnel.ts index 109e755dca2..f8d9c92b20c 100644 --- a/packages/cli-kit/src/public/node/plugins/tunnel.ts +++ b/packages/cli-kit/src/public/node/plugins/tunnel.ts @@ -33,15 +33,11 @@ export class TunnelError extends ExtendableError { export interface HookReturnPerTunnelPlugin { tunnel_start: { options: {port: number; provider: string} - pluginReturns: { - [key: string]: Result - } + pluginReturns: Record> } tunnel_provider: { - options: {[key: string]: never} - pluginReturns: { - [pluginName: string]: {name: string} - } + options: Record + pluginReturns: Record } } diff --git a/packages/cli-kit/src/public/node/result.test.ts b/packages/cli-kit/src/public/node/result.test.ts index 89428e0b749..67486603925 100644 --- a/packages/cli-kit/src/public/node/result.test.ts +++ b/packages/cli-kit/src/public/node/result.test.ts @@ -1,6 +1,6 @@ import {err, ok} from './result.js' import {mockAndCaptureOutput} from './testing/output.js' -import {outputSuccess} from '../../public/node/output.js' +import {outputSuccess} from './output.js' import {describe, expect, test} from 'vitest' describe('ok', () => { diff --git a/packages/cli-kit/src/public/node/result.ts b/packages/cli-kit/src/public/node/result.ts index 8fd69576b58..4e4f89e4b71 100644 --- a/packages/cli-kit/src/public/node/result.ts +++ b/packages/cli-kit/src/public/node/result.ts @@ -78,7 +78,7 @@ export class Ok { } export class Err { - // eslint-disable-next-line node/handle-callback-err + // eslint-disable-next-line n/handle-callback-err constructor(readonly error: TError) {} /** diff --git a/packages/cli-kit/src/public/node/session-prompt.test.ts b/packages/cli-kit/src/public/node/session-prompt.test.ts index 6c249ca3a4e..7b9e983a300 100644 --- a/packages/cli-kit/src/public/node/session-prompt.test.ts +++ b/packages/cli-kit/src/public/node/session-prompt.test.ts @@ -5,6 +5,7 @@ import {identityFqdn} from './context/fqdn.js' import {setCurrentSessionId} from '../../private/node/conf-store.js' import * as sessionStore from '../../private/node/session/store.js' import {Sessions} from '../../private/node/session/schema.js' + import {describe, expect, vi, test, beforeEach} from 'vitest' vi.mock('./ui.js') diff --git a/packages/cli-kit/src/public/node/session.test.ts b/packages/cli-kit/src/public/node/session.test.ts index 13c6f0fb278..962a48ac8c0 100644 --- a/packages/cli-kit/src/public/node/session.test.ts +++ b/packages/cli-kit/src/public/node/session.test.ts @@ -17,6 +17,7 @@ import { exchangeCliTokenForAppManagementAccessToken, exchangeCliTokenForBusinessPlatformAccessToken, } from '../../private/node/session/exchange.js' + import {vi, describe, expect, test} from 'vitest' const futureDate = new Date(2022, 1, 1, 11) diff --git a/packages/cli-kit/src/public/node/session.ts b/packages/cli-kit/src/public/node/session.ts index f7550df0f58..5d5895c06d1 100644 --- a/packages/cli-kit/src/public/node/session.ts +++ b/packages/cli-kit/src/public/node/session.ts @@ -1,14 +1,14 @@ -import {AbortError, BugError} from './error.js' -import {getPartnersToken} from './environment.js' -import {nonRandomUUID} from './crypto.js' import {shopifyFetch} from './http.js' +import {nonRandomUUID} from './crypto.js' +import {getPartnersToken} from './environment.js' +import {AbortError, BugError} from './error.js' +import {outputContent, outputToken, outputDebug} from './output.js' import * as sessionStore from '../../private/node/session/store.js' import { exchangeCustomPartnerToken, exchangeCliTokenForAppManagementAccessToken, exchangeCliTokenForBusinessPlatformAccessToken, } from '../../private/node/session/exchange.js' -import {outputContent, outputToken, outputDebug} from '../../public/node/output.js' import { AdminAPIScope, AppManagementAPIScope, diff --git a/packages/cli-kit/src/public/node/system.test.ts b/packages/cli-kit/src/public/node/system.test.ts index 6019d294ae9..0483f11e315 100644 --- a/packages/cli-kit/src/public/node/system.test.ts +++ b/packages/cli-kit/src/public/node/system.test.ts @@ -3,6 +3,7 @@ import {execa} from 'execa' import {describe, expect, test, vi} from 'vitest' import which from 'which' import {Readable} from 'stream' + import * as fs from 'fs' vi.mock('which') diff --git a/packages/cli-kit/src/public/node/system.ts b/packages/cli-kit/src/public/node/system.ts index b9064174315..156b4c6de75 100644 --- a/packages/cli-kit/src/public/node/system.ts +++ b/packages/cli-kit/src/public/node/system.ts @@ -5,16 +5,17 @@ import {treeKill} from './tree-kill.js' import {isTruthy} from './context/utilities.js' import {renderWarning} from './ui.js' import {platformAndArch} from './os.js' -import {shouldDisplayColors, outputDebug} from '../../public/node/output.js' +import {shouldDisplayColors, outputDebug} from './output.js' import {execa, ExecaChildProcess} from 'execa' import which from 'which' import {delimiter} from 'pathe' + import {fstatSync} from 'fs' import type {Writable, Readable} from 'stream' export interface ExecOptions { cwd?: string - env?: {[key: string]: string | undefined} + env?: Record stdin?: Readable | 'inherit' stdout?: Writable | 'inherit' stderr?: Writable | 'inherit' diff --git a/packages/cli-kit/src/public/node/tcp.ts b/packages/cli-kit/src/public/node/tcp.ts index 81f9f9f23e7..86d05ec552e 100644 --- a/packages/cli-kit/src/public/node/tcp.ts +++ b/packages/cli-kit/src/public/node/tcp.ts @@ -1,6 +1,6 @@ import {sleep} from './system.js' import {AbortError} from './error.js' -import {outputDebug, outputContent, outputToken} from '../../public/node/output.js' +import {outputDebug, outputContent, outputToken} from './output.js' import * as port from 'get-port-please' interface GetTCPPortOptions { diff --git a/packages/cli-kit/src/public/node/testing/output.ts b/packages/cli-kit/src/public/node/testing/output.ts index b22c4fc3eed..75fd042d41a 100644 --- a/packages/cli-kit/src/public/node/testing/output.ts +++ b/packages/cli-kit/src/public/node/testing/output.ts @@ -1,4 +1,4 @@ -import {collectedLogs, clearCollectedLogs} from '../../../public/node/output.js' +import {collectedLogs, clearCollectedLogs} from '../output.js' interface OutputMock { output: () => string diff --git a/packages/cli-kit/src/public/node/themes/api.test.ts b/packages/cli-kit/src/public/node/themes/api.test.ts index d3dc4e06736..1eb6702b0e0 100644 --- a/packages/cli-kit/src/public/node/themes/api.test.ts +++ b/packages/cli-kit/src/public/node/themes/api.test.ts @@ -26,6 +26,7 @@ import {GetThemes} from '../../../cli/api/graphql/admin/generated/get_themes.js' import {GetTheme} from '../../../cli/api/graphql/admin/generated/get_theme.js' import {adminRequestDoc, supportedApiVersions} from '../api/admin.js' import {AbortError} from '../error.js' + import {test, vi, expect, describe, beforeEach} from 'vitest' import {ClientError} from 'graphql-request' diff --git a/packages/cli-kit/src/public/node/themes/api.ts b/packages/cli-kit/src/public/node/themes/api.ts index 2af4ad3295b..3c4d2b72ce9 100644 --- a/packages/cli-kit/src/public/node/themes/api.ts +++ b/packages/cli-kit/src/public/node/themes/api.ts @@ -1,6 +1,6 @@ -import {composeThemeGid, parseGid, DEVELOPMENT_THEME_ROLE} from './utils.js' -import {buildTheme} from './factories.js' import {Result, Checksum, Key, Theme, ThemeAsset, Operation} from './types.js' +import {buildTheme} from './factories.js' +import {composeThemeGid, parseGid, DEVELOPMENT_THEME_ROLE} from './utils.js' import {ThemeUpdate} from '../../../cli/api/graphql/admin/generated/theme_update.js' import {ThemeDelete} from '../../../cli/api/graphql/admin/generated/theme_delete.js' import {ThemeDuplicate} from '../../../cli/api/graphql/admin/generated/theme_duplicate.js' @@ -374,7 +374,7 @@ export async function fetchChecksums(id: number, session: AdminSession): Promise export async function themeUpdate(id: number, params: ThemeParams, session: AdminSession): Promise { const name = params.name - const input: {[key: string]: string} = {} + const input: Record = {} if (name) { input.name = name } diff --git a/packages/cli-kit/src/public/node/themes/conf.ts b/packages/cli-kit/src/public/node/themes/conf.ts index 936aeec1805..515dcda18ce 100644 --- a/packages/cli-kit/src/public/node/themes/conf.ts +++ b/packages/cli-kit/src/public/node/themes/conf.ts @@ -5,9 +5,7 @@ import {outputDebug, outputContent} from '../output.js' type HostThemeId = string type StoreFqdn = AdminSession['storeFqdn'] -interface HostThemeLocalStorageSchema { - [themeStore: StoreFqdn]: HostThemeId -} +type HostThemeLocalStorageSchema = Record let _hostThemeLocalStorageInstance: LocalStorage | undefined diff --git a/packages/cli-kit/src/public/node/tree-kill.ts b/packages/cli-kit/src/public/node/tree-kill.ts index 021ffb398e7..f4b4570c23f 100644 --- a/packages/cli-kit/src/public/node/tree-kill.ts +++ b/packages/cli-kit/src/public/node/tree-kill.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable @typescript-eslint/ban-ts-comment */ /* eslint-disable jsdoc/require-throws */ /* eslint-disable no-restricted-imports */ @@ -6,9 +5,7 @@ import {outputDebug} from './output.js' import {exec, spawn} from 'child_process' -interface ProcessTree { - [key: string]: string[] -} +type ProcessTree = Record type AfterKillCallback = (error?: Error) => void diff --git a/packages/cli-kit/src/public/node/ui.test.ts b/packages/cli-kit/src/public/node/ui.test.ts index 61a1ef3ceac..f119b5de08c 100644 --- a/packages/cli-kit/src/public/node/ui.test.ts +++ b/packages/cli-kit/src/public/node/ui.test.ts @@ -14,6 +14,7 @@ import {mockAndCaptureOutput} from './testing/output.js' import {TokenizedString} from './output.js' import {afterEach, beforeEach, describe, expect, test, vi} from 'vitest' import supportsHyperlinks from 'supports-hyperlinks' + import {Writable} from 'stream' vi.mock('supports-hyperlinks') diff --git a/packages/cli-kit/src/public/node/ui.tsx b/packages/cli-kit/src/public/node/ui.tsx index 7f234a77f9c..c9ac3e6b3c7 100644 --- a/packages/cli-kit/src/public/node/ui.tsx +++ b/packages/cli-kit/src/public/node/ui.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable tsdoc/syntax */ import {AbortError, AbortSilentError, FatalError as Fatal} from './error.js' import {outputContent, outputDebug, outputToken, TokenizedString} from './output.js' @@ -31,6 +30,7 @@ import {AutocompletePromptProps, AutocompletePrompt} from '../../private/node/ui import {InfoTableSection} from '../../private/node/ui/components/Prompts/InfoTable.js' import {InfoMessageProps} from '../../private/node/ui/components/Prompts/InfoMessage.js' import {SingleTask} from '../../private/node/ui/components/SingleTask.js' + import React from 'react' import {Key as InkKey, RenderOptions} from 'ink' @@ -235,7 +235,7 @@ interface RenderFatalErrorOptions { * [1] https://partners.shopify.com/signup * */ -// eslint-disable-next-line max-params + export function renderFatalError(error: Fatal, {renderOptions}: RenderFatalErrorOptions = {}) { return renderOnce(, {logLevel: 'error', renderOptions}) } @@ -276,7 +276,7 @@ export interface RenderSelectPromptOptions extends Omit, * Press ↑↓ arrows to select, enter to confirm. * */ -// eslint-disable-next-line max-params + export async function renderSelectPrompt( {renderOptions, isConfirmationPrompt, ...props}: RenderSelectPromptOptions, uiDebugOptions: UIDebugOptions = defaultUIDebugOptions, @@ -301,8 +301,10 @@ export async function renderSelectPrompt( }) } -export interface RenderConfirmationPromptOptions - extends Pick, 'message' | 'infoTable' | 'infoMessage' | 'abortSignal'> { +export interface RenderConfirmationPromptOptions extends Pick< + SelectPromptProps, + 'message' | 'infoTable' | 'infoMessage' | 'abortSignal' +> { confirmationMessage?: string cancellationMessage?: string renderOptions?: RenderOptions @@ -363,8 +365,10 @@ export async function renderConfirmationPrompt({ }) } -export interface RenderAutocompleteOptions - extends PartialBy, 'onSubmit'>, 'search'> { +export interface RenderAutocompleteOptions extends PartialBy< + Omit, 'onSubmit'>, + 'search' +> { renderOptions?: RenderOptions } @@ -406,7 +410,7 @@ export interface RenderAutocompleteOptions * Press ↑↓ arrows to select, enter to confirm. * */ -// eslint-disable-next-line max-params + export async function renderAutocompletePrompt( {renderOptions, ...props}: RenderAutocompleteOptions, uiDebugOptions: UIDebugOptions = defaultUIDebugOptions, @@ -478,12 +482,11 @@ interface RenderTasksOptions { * ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ * Installing dependencies ... */ -// eslint-disable-next-line max-params + export async function renderTasks( tasks: Task[], {renderOptions, noProgressBar}: RenderTasksOptions = {}, ) { - // eslint-disable-next-line max-params return new Promise((resolve, reject) => { render(, { ...renderOptions, @@ -518,7 +521,6 @@ export async function renderSingleTask({ onAbort, renderOptions, }: RenderSingleTaskOptions): Promise { - // eslint-disable-next-line max-params return new Promise((resolve, reject) => { render(, { ...renderOptions, @@ -539,7 +541,7 @@ export interface RenderTextPromptOptions extends Omit { throwInNonTTY({message: 'Press any key'}, uiDebugOptions) return runWithTimer('cmd_all_timing_prompts_ms')(() => { - // eslint-disable-next-line max-params return new Promise((resolve, reject) => { const handler = (buffer: Buffer) => { stdin.setRawMode(false) @@ -661,7 +662,6 @@ interface ThrowInNonTTYOptions { stdin?: NodeJS.ReadStream } -// eslint-disable-next-line max-params function throwInNonTTY({message, stdin = undefined}: ThrowInNonTTYOptions, uiDebugOptions: UIDebugOptions) { if (isTTY({stdin, uiDebugOptions})) return diff --git a/packages/cli-kit/src/public/node/vendor/dev_server/dev-server-2016.ts b/packages/cli-kit/src/public/node/vendor/dev_server/dev-server-2016.ts index 251dec20250..9d9a6d4d8d6 100644 --- a/packages/cli-kit/src/public/node/vendor/dev_server/dev-server-2016.ts +++ b/packages/cli-kit/src/public/node/vendor/dev_server/dev-server-2016.ts @@ -1,10 +1,14 @@ -import fs from 'fs' -import * as os from 'node:os' - import {assertConnectable} from './network/index.js' import {assertCompatibleEnvironment} from './env.js' import {HostOptions} from './types.js' +import * as os from 'node:os' + +import fs from 'fs' +/** + * + * @param projectName + */ export function createServer(projectName: string) { return { host: (options: HostOptions = {}) => host(projectName, options), @@ -42,6 +46,10 @@ function getAddrPort(name: string): [string, number] { // Allow overrides for more concise test setup. Meh. let assertRunningOverride: typeof assertRunning2016 | undefined +/** + * + * @param override + */ export function setAssertRunning(override: typeof assertRunningOverride) { assertRunningOverride = override } diff --git a/packages/cli-kit/src/public/node/vendor/dev_server/dev-server-2024.ts b/packages/cli-kit/src/public/node/vendor/dev_server/dev-server-2024.ts index 2882024d84b..5f9e4250a88 100644 --- a/packages/cli-kit/src/public/node/vendor/dev_server/dev-server-2024.ts +++ b/packages/cli-kit/src/public/node/vendor/dev_server/dev-server-2024.ts @@ -1,14 +1,17 @@ -import fs from 'node:fs' - +import {assertConnectable, getIpFromHosts} from './network/index.js' +import {assertCompatibleEnvironment} from './env.js' import * as ni from 'network-interfaces' +import fs from 'node:fs' import type {HostOptions} from './types.js' -import {assertConnectable, getIpFromHosts} from './network/index.js' -import {assertCompatibleEnvironment} from './env.js' const NON_SHOP_PREFIXES = ['app', 'dev', 'shopify'] const BACKEND_PORT = 8080 +/** + * + * @param projectName + */ export function createServer(projectName: string) { return { host: (options: HostOptions = {}) => host(projectName, options), @@ -75,6 +78,10 @@ function resolveBackendHost(name: string): string { // Allow overrides for more concise test setup. Meh. let assertRunningOverride: typeof assertRunning2024 | undefined +/** + * + * @param override + */ export function setAssertRunning(override: typeof assertRunningOverride) { assertRunningOverride = override } diff --git a/packages/cli-kit/src/public/node/vendor/dev_server/dev-server.ts b/packages/cli-kit/src/public/node/vendor/dev_server/dev-server.ts index 583059281c4..d4d8a4767ef 100644 --- a/packages/cli-kit/src/public/node/vendor/dev_server/dev-server.ts +++ b/packages/cli-kit/src/public/node/vendor/dev_server/dev-server.ts @@ -1,7 +1,7 @@ -import fs from 'node:fs' - import {createServer as createServer2024} from './dev-server-2024.js' import {createServer as createServer2016} from './dev-server-2016.js' +import fs from 'node:fs' + import type {DevServer as DevServerType, DevServerCore as DevServerCoreType, HostOptions} from './types.js' export {isDevServerEnvironment} from './env.js' diff --git a/packages/cli-kit/src/public/node/vendor/dev_server/env.ts b/packages/cli-kit/src/public/node/vendor/dev_server/env.ts index d46214f5d7b..a9babed50c3 100644 --- a/packages/cli-kit/src/public/node/vendor/dev_server/env.ts +++ b/packages/cli-kit/src/public/node/vendor/dev_server/env.ts @@ -1,5 +1,8 @@ export const isDevServerEnvironment = process.env.USING_DEV === '1' +/** + * + */ export function assertCompatibleEnvironment() { if (!isDevServerEnvironment) { throw new Error('DevServer is not supported in this environment') diff --git a/packages/cli-kit/src/public/node/vendor/dev_server/network/host.ts b/packages/cli-kit/src/public/node/vendor/dev_server/network/host.ts index 6580f94c4da..8ed119ccdb9 100644 --- a/packages/cli-kit/src/public/node/vendor/dev_server/network/host.ts +++ b/packages/cli-kit/src/public/node/vendor/dev_server/network/host.ts @@ -1,5 +1,4 @@ import fs from 'node:fs' -import path from 'node:path' const HOSTS_FILE = '/etc/hosts' @@ -38,6 +37,10 @@ function loadHostsFile() { } } +/** + * + * @param hostname + */ export function getIpFromHosts(hostname: string) { loadHostsFile() @@ -49,7 +52,9 @@ export function getIpFromHosts(hostname: string) { throw new Error(`No IP found for hostname: ${hostname}`) } -// eslint-disable-next-line @typescript-eslint/naming-convention +/** + * + */ export function TEST_ClearCache() { hostToIpCache = {} lastModifiedTime = 0 diff --git a/packages/cli-kit/src/public/node/vendor/dev_server/network/index.ts b/packages/cli-kit/src/public/node/vendor/dev_server/network/index.ts index 2f441c13cd5..83de5c61030 100644 --- a/packages/cli-kit/src/public/node/vendor/dev_server/network/index.ts +++ b/packages/cli-kit/src/public/node/vendor/dev_server/network/index.ts @@ -1,5 +1,4 @@ import {spawnSync} from 'node:child_process' -import path from 'node:path' export {getIpFromHosts} from './host.js' @@ -10,12 +9,15 @@ export interface ConnectionArguments { timeout?: number } -// eslint-disable-next-line prettier/prettier const DEFAULT_CONNECT_TIMEOUT = 1000 // Skip initialization on module load to prevent Spin trying to load a macOS dylib // (port checks should never run on Spin anyway) let checkPort: ReturnType +/** + * + * @param options + */ export function assertConnectable(options: ConnectionArguments): void { checkPort ||= getCheckPortHelper() @@ -33,7 +35,9 @@ export function assertConnectable(options: ConnectionArguments): void { } } -// eslint-disable-next-line @typescript-eslint/naming-convention +/** + * + */ export function TEST_testResetCheckPort(): void { checkPort = getCheckPortHelper() } diff --git a/packages/cli-kit/src/public/node/vendor/otel-js/export/InstantaneousMetricReader.ts b/packages/cli-kit/src/public/node/vendor/otel-js/export/InstantaneousMetricReader.ts index 9ac92bbf893..1ceb2bd6e08 100644 --- a/packages/cli-kit/src/public/node/vendor/otel-js/export/InstantaneousMetricReader.ts +++ b/packages/cli-kit/src/public/node/vendor/otel-js/export/InstantaneousMetricReader.ts @@ -1,9 +1,8 @@ -import type {PushMetricExporter} from '@opentelemetry/sdk-metrics' +import {throttle} from '../utils/throttle.js' import {MetricReader} from '@opentelemetry/sdk-metrics' import {ExportResultCode} from '@opentelemetry/core' import {diag} from '@opentelemetry/api' - -import {throttle} from '../utils/throttle.js' +import type {PushMetricExporter} from '@opentelemetry/sdk-metrics' export interface InstantaneousMetricReaderOptions { /** @@ -27,11 +26,7 @@ export class InstantaneousMetricReader extends MetricReader { }) this._exporter = exporter - this.onForceFlush = throttle( - // eslint-disable-next-line @typescript-eslint/unbound-method - this.onForceFlush, - throttleLimit, - ) + this.onForceFlush = throttle(this.onForceFlush, throttleLimit) } protected async onForceFlush(): Promise { diff --git a/packages/cli-kit/src/public/node/vendor/otel-js/service/BaseOtelService/BaseOtelService.ts b/packages/cli-kit/src/public/node/vendor/otel-js/service/BaseOtelService/BaseOtelService.ts index 069eb035a24..436193b15f7 100644 --- a/packages/cli-kit/src/public/node/vendor/otel-js/service/BaseOtelService/BaseOtelService.ts +++ b/packages/cli-kit/src/public/node/vendor/otel-js/service/BaseOtelService/BaseOtelService.ts @@ -1,6 +1,8 @@ +import {MetricInstrumentType} from '../types.js' +import {isValidMetricName} from '../../utils/validators.js' +import {ExplicitBucketHistogramAggregation, View} from '@opentelemetry/sdk-metrics' import type {MetricAttributes} from '@opentelemetry/api' import type {MeterProvider, ViewOptions} from '@opentelemetry/sdk-metrics' -import {ExplicitBucketHistogramAggregation, View} from '@opentelemetry/sdk-metrics' import type { MetricDescriptor, @@ -10,8 +12,6 @@ import type { OtelService, RecordMetricFunction, } from '../types.js' -import {MetricInstrumentType} from '../types.js' -import {isValidMetricName} from '../../utils/validators.js' const instrumentationScope = 'opentelemetry-js-shopify-web' @@ -53,6 +53,13 @@ export class BaseOtelService implements OtelService { /** * Bootstraps an Otel exporter which can send Otel metrics to a dedicated Shopify supported collector endpoint. + * + * @param root0 + * @param root0.serviceName + * @param root0.prefixMetric + * @param root0.metrics + * @param root0.onRecord + * @param root0.meterProvider */ constructor({serviceName, prefixMetric = false, metrics = {}, onRecord, meterProvider}: BaseOtelServiceOptions) { if (!serviceName) { @@ -78,6 +85,7 @@ export class BaseOtelService implements OtelService { addView(viewOptions: ViewOptions) { // The API to register view is not yet exposed. We need to use the private // property to register a new view after the initial instantiation. + // eslint-disable-next-line @typescript-eslint/no-explicit-any ;(this.meterProvider as any)._sharedState?.viewRegistry?.addView?.(new View(viewOptions)) } diff --git a/packages/cli-kit/src/public/node/vendor/otel-js/service/DefaultOtelService/DefaultOtelService.ts b/packages/cli-kit/src/public/node/vendor/otel-js/service/DefaultOtelService/DefaultOtelService.ts index 1c7c4fc0ffb..5c1aa9104bf 100644 --- a/packages/cli-kit/src/public/node/vendor/otel-js/service/DefaultOtelService/DefaultOtelService.ts +++ b/packages/cli-kit/src/public/node/vendor/otel-js/service/DefaultOtelService/DefaultOtelService.ts @@ -6,7 +6,7 @@ import type {BaseOtelServiceOptions} from '../BaseOtelService/BaseOtelService.js export interface DefaultOtelServiceOptions extends BaseOtelServiceOptions { /** - * What environment is being deployed (production, staging) + * What environment is being deployed (production, staging). */ env?: string /** @@ -25,6 +25,17 @@ export interface DefaultOtelServiceOptions extends BaseOtelServiceOptions { export class DefaultOtelService extends BaseOtelService { /** * Bootstraps an Otel exporter which can send Otel metrics to a dedicated Shopify supported collector endpoint. + * + * @param root0 + * @param root0.throttleLimit + * @param root0.env + * @param root0.serviceName + * @param root0.prefixMetric + * @param root0.metrics + * @param root0.onRecord + * @param root0.meterProvider + * @param root0.useXhr + * @param root0.otelEndpoint */ constructor({ throttleLimit = 5000, diff --git a/packages/cli-kit/src/public/node/vendor/otel-js/service/types.ts b/packages/cli-kit/src/public/node/vendor/otel-js/service/types.ts index b17e7da59c6..dde478922cc 100644 --- a/packages/cli-kit/src/public/node/vendor/otel-js/service/types.ts +++ b/packages/cli-kit/src/public/node/vendor/otel-js/service/types.ts @@ -9,19 +9,19 @@ import type { import type {ViewOptions} from '@opentelemetry/sdk-metrics' export type CustomMetricLabels< - TLabels extends {[key in TKeys]: MetricAttributes}, + TLabels extends Record, TKeys extends string = keyof TLabels & string, > = { [P in TKeys]: TLabels[P] extends MetricAttributes ? TLabels[P] : never } -export type MetricRecording = [value: number, labels?: TAttributes] +export type MetricRecording = [value: number, labels?: TAttributes] -export type RecordMetricFunction = ( +export type RecordMetricFunction = ( ...args: MetricRecording ) => void -export type OnRecordCallback = ( +export type OnRecordCallback = ( metricName: string, ...args: MetricRecording ) => MetricRecording | void @@ -48,9 +48,7 @@ export type MetricDescriptor = MetricOptions & } ) -export interface MetricsConfig { - [key: string]: MetricDescriptor -} +export type MetricsConfig = Record export interface OtelService { readonly serviceName: string @@ -59,7 +57,7 @@ export interface OtelService { addView(viewOptions: ViewOptions): void - record(...args: Parameters>): void + record(...args: Parameters>): void /** * `onRecord` callback is called when a metric is recorded. diff --git a/packages/cli-kit/src/public/node/vendor/otel-js/utils/throttle.ts b/packages/cli-kit/src/public/node/vendor/otel-js/utils/throttle.ts index 3880ea298be..1d87007c8b0 100644 --- a/packages/cli-kit/src/public/node/vendor/otel-js/utils/throttle.ts +++ b/packages/cli-kit/src/public/node/vendor/otel-js/utils/throttle.ts @@ -1,18 +1,26 @@ -type ThrottledFunction any> = (...args: Parameters) => ReturnType +type ThrottledFunction unknown> = (...args: Parameters) => ReturnType interface ThrottleOptions { leading?: boolean trailing?: boolean } -export function throttle any>( +/** + * + * @param func + * @param wait + * @param root0 + * @param root0.leading + * @param root0.trailing + */ +export function throttle unknown>( func: T, wait: number, {leading = true, trailing = true}: ThrottleOptions = {}, ): ThrottledFunction { let lastArgs: Parameters | null let result: ReturnType - let context: any + let context: unknown let timeout: ReturnType | null = null let previous = 0 @@ -20,13 +28,13 @@ export function throttle any>( previous = leading === false ? 0 : Date.now() timeout = null if (lastArgs) { - result = func.apply(context, lastArgs) + result = func.apply(context, lastArgs) as ReturnType } context = null lastArgs = null } - return function (this: any, ...args: Parameters): ReturnType { + return function (this: unknown, ...args: Parameters): ReturnType { const now = Date.now() if (!previous && leading === false) previous = now @@ -41,7 +49,7 @@ export function throttle any>( } previous = now if (lastArgs) { - result = func.apply(context, lastArgs) + result = func.apply(context, lastArgs) as ReturnType } context = null lastArgs = null diff --git a/packages/cli-kit/src/public/node/vendor/otel-js/utils/validators.ts b/packages/cli-kit/src/public/node/vendor/otel-js/utils/validators.ts index eaad540c59b..31450f07057 100644 --- a/packages/cli-kit/src/public/node/vendor/otel-js/utils/validators.ts +++ b/packages/cli-kit/src/public/node/vendor/otel-js/utils/validators.ts @@ -2,6 +2,10 @@ import {diag} from '@opentelemetry/api' const validMetricRegex = new RegExp('[^a-zA-Z_][^a-zA-Z0-9_]*') +/** + * + * @param value + */ export function isValidMetricName(value: string): boolean { if (validMetricRegex.test(value)) { diag.warn( diff --git a/packages/cli-kit/src/public/node/version.test.ts b/packages/cli-kit/src/public/node/version.test.ts index 99bced0963f..98f3ce67a1c 100644 --- a/packages/cli-kit/src/public/node/version.test.ts +++ b/packages/cli-kit/src/public/node/version.test.ts @@ -1,7 +1,8 @@ +import {captureOutput} from './system.js' import {localCLIVersion, globalCLIVersion, isPreReleaseVersion} from './version.js' -import {inTemporaryDirectory} from '../node/fs.js' -import {captureOutput} from '../node/system.js' +import {inTemporaryDirectory} from './fs.js' import {describe, expect, test, vi} from 'vitest' + import which from 'which' vi.mock('../node/system.js') diff --git a/packages/cli-kit/src/public/node/version.ts b/packages/cli-kit/src/public/node/version.ts index 3c958889471..fa91dfe54d3 100644 --- a/packages/cli-kit/src/public/node/version.ts +++ b/packages/cli-kit/src/public/node/version.ts @@ -1,4 +1,4 @@ -import {captureOutput} from '../node/system.js' +import {captureOutput} from './system.js' import which from 'which' import {satisfies} from 'semver' /** diff --git a/packages/cli-kit/src/public/node/vscode.ts b/packages/cli-kit/src/public/node/vscode.ts index 1417e47defe..0962bf9c10f 100644 --- a/packages/cli-kit/src/public/node/vscode.ts +++ b/packages/cli-kit/src/public/node/vscode.ts @@ -1,6 +1,6 @@ import {fileExists, writeFile, readFile, findPathUp} from './fs.js' import {joinPath, cwd} from './path.js' -import {outputContent, outputToken, outputDebug} from '../../public/node/output.js' +import {outputContent, outputToken, outputDebug} from './output.js' /** * Check if user editor is VS Code. diff --git a/packages/cli/bin/bundle.js b/packages/cli/bin/bundle.js index 78de3e4ace5..574bcff876d 100644 --- a/packages/cli/bin/bundle.js +++ b/packages/cli/bin/bundle.js @@ -1,13 +1,15 @@ /* eslint-disable @shopify/cli/specific-imports-in-bootstrap-code, @nx/enforce-module-boundaries */ -import ShopifyStacktraceyPlugin from '../../../bin/bundling/esbuild-plugin-stacktracey.js' -import ShopifyVSCodePlugin from '../../../bin/bundling/esbuild-plugin-vscode.js' -import GraphiQLImportsPlugin from '../../../bin/bundling/esbuild-plugin-graphiql-imports.js' -import CliKitDedupPlugin from '../../../bin/bundling/esbuild-plugin-dedup-cli-kit.js' +import {createRequire} from 'module' + import {build as esBuild} from 'esbuild' import {copy} from 'esbuild-plugin-copy' import glob from 'fast-glob' import {joinPath, dirname} from '@shopify/cli-kit/node/path' -import {createRequire} from 'module' + +import ShopifyStacktraceyPlugin from '../../../bin/bundling/esbuild-plugin-stacktracey.js' +import ShopifyVSCodePlugin from '../../../bin/bundling/esbuild-plugin-vscode.js' +import GraphiQLImportsPlugin from '../../../bin/bundling/esbuild-plugin-graphiql-imports.js' +import CliKitDedupPlugin from '../../../bin/bundling/esbuild-plugin-dedup-cli-kit.js' const require = createRequire(import.meta.url) diff --git a/packages/cli/bin/dev.js b/packages/cli/bin/dev.js index b4be256213d..da29908c490 100755 --- a/packages/cli/bin/dev.js +++ b/packages/cli/bin/dev.js @@ -1,7 +1,5 @@ -#!/usr/bin/env node +import runCLI from '../dist/index.js' process.removeAllListeners('warning') -import runCLI from '../dist/index.js' - runCLI({development: true}) diff --git a/packages/cli/bin/run.js b/packages/cli/bin/run.js index 4cf1930ffc3..6cc0c0bc3cc 100755 --- a/packages/cli/bin/run.js +++ b/packages/cli/bin/run.js @@ -1,7 +1,7 @@ #!/usr/bin/env node -process.removeAllListeners('warning') - import runCLI from '../dist/index.js' +process.removeAllListeners('warning') + runCLI({development: false}) diff --git a/packages/cli/src/cli/commands/kitchen-sink/index.test.ts b/packages/cli/src/cli/commands/kitchen-sink/index.test.ts index e271ee24943..c761240578c 100644 --- a/packages/cli/src/cli/commands/kitchen-sink/index.test.ts +++ b/packages/cli/src/cli/commands/kitchen-sink/index.test.ts @@ -2,6 +2,7 @@ import KitchenSinkAll from './index.js' import {asyncTasks as asyncTasksService} from '../../services/kitchen-sink/async.js' import {staticService} from '../../services/kitchen-sink/static.js' import {prompts as promptsService} from '../../services/kitchen-sink/prompts.js' + import {describe, test, vi, expect} from 'vitest' vi.mock('../../services/kitchen-sink/prompts.js') diff --git a/packages/cli/src/cli/services/upgrade.test.ts b/packages/cli/src/cli/services/upgrade.test.ts index 08407731792..f53ede7a01f 100644 --- a/packages/cli/src/cli/services/upgrade.test.ts +++ b/packages/cli/src/cli/services/upgrade.test.ts @@ -1,5 +1,5 @@ -import {upgrade} from './upgrade.js' import * as upgradeService from './upgrade.js' +import {upgrade} from './upgrade.js' import {afterEach, beforeEach, describe, expect, vi, test} from 'vitest' import {platformAndArch} from '@shopify/cli-kit/node/os' import * as nodePackageManager from '@shopify/cli-kit/node/node-package-manager' diff --git a/packages/cli/src/cli/services/upgrade.ts b/packages/cli/src/cli/services/upgrade.ts index 0ae3524bd3d..32e0c66c0bd 100644 --- a/packages/cli/src/cli/services/upgrade.ts +++ b/packages/cli/src/cli/services/upgrade.ts @@ -146,7 +146,7 @@ function outputUpgradeMessage(currentVersion: string, newestVersion: string): vo async function installJsonDependencies( depsEnv: DependencyType, - deps: {[key: string]: string}, + deps: Record, directory: string, ): Promise { const packagesToUpdate = [await cliDependency(), ...(await oclifPlugins())] diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 1fd491d8c90..77759cbd0b6 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -24,6 +24,7 @@ import {DidYouMeanCommands} from '@shopify/plugin-did-you-mean' import {runCLI} from '@shopify/cli-kit/node/cli' import {renderFatalError} from '@shopify/cli-kit/node/ui' import {FatalError} from '@shopify/cli-kit/node/error' + import fs from 'fs' export {DidYouMeanHook} from '@shopify/plugin-did-you-mean' diff --git a/packages/features/steps/app.steps.ts b/packages/features/steps/app.steps.ts index f0dd1330894..9d4b99ee946 100644 --- a/packages/features/steps/app.steps.ts +++ b/packages/features/steps/app.steps.ts @@ -4,6 +4,7 @@ import {AppInfo} from '../world/index.js' import * as path from 'pathe' import {When, Then} from '@cucumber/cucumber' import fs from 'fs-extra' + import {strict as assert} from 'assert' When( @@ -102,7 +103,7 @@ interface GenerateExtensionArgs { type: string directory: string extraArgs: string[] - env: {[key: string]: string} + env: Record } async function generateExtension({name, type, directory, extraArgs, env}: GenerateExtensionArgs) { try { diff --git a/packages/features/steps/create-app.steps.ts b/packages/features/steps/create-app.steps.ts index 8b17a44a619..f5aeeb6705f 100644 --- a/packages/features/steps/create-app.steps.ts +++ b/packages/features/steps/create-app.steps.ts @@ -3,6 +3,7 @@ import {exec} from '../lib/system.js' import {When, Then} from '@cucumber/cucumber' import * as path from 'pathe' import fs from 'fs-extra' + import {strict as assert} from 'assert' interface ExtensionConfiguration { diff --git a/packages/features/steps/github-actions.steps.ts b/packages/features/steps/github-actions.steps.ts index 24c91c97d6a..8e5cb346987 100644 --- a/packages/features/steps/github-actions.steps.ts +++ b/packages/features/steps/github-actions.steps.ts @@ -2,6 +2,7 @@ import {exec} from '../lib/system.js' import {When, Then} from '@cucumber/cucumber' import * as path from 'pathe' import {strict as assert} from 'assert' + import {fileURLToPath} from 'url' const __filename = fileURLToPath(import.meta.url) diff --git a/packages/features/steps/node-deps.steps.ts b/packages/features/steps/node-deps.steps.ts index 6d0366360b6..89b19334725 100644 --- a/packages/features/steps/node-deps.steps.ts +++ b/packages/features/steps/node-deps.steps.ts @@ -9,10 +9,10 @@ const __filename = fileURLToPath(import.meta.url) const __dirname = path.dirname(__filename) interface PackageJson { - dependencies?: {[key: string]: string} - devDependencies?: {[key: string]: string} - peerDependencies?: {[key: string]: string} - resolutions?: {[key: string]: string} + dependencies?: Record + devDependencies?: Record + peerDependencies?: Record + resolutions?: Record } async function parsePackageJson(path: string): Promise { @@ -22,7 +22,6 @@ async function parsePackageJson(path: string): Promise { When(/I look at the package.json files in all packages/, async function () { this.packageJsonMap = {} for (const packageJson of glob.sync(`${__dirname}/../../*/package.json`)) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const packageName = path.dirname(packageJson).split('/').pop()! // eslint-disable-next-line no-await-in-loop this.packageJsonMap[packageName] = await parsePackageJson(packageJson) diff --git a/packages/features/world/index.ts b/packages/features/world/index.ts index 1491259cd5a..28b0c9de684 100644 --- a/packages/features/world/index.ts +++ b/packages/features/world/index.ts @@ -24,7 +24,7 @@ export interface ExtensionConfiguration { export class World { public temporaryDirectory: string - public temporaryEnv: {[key: string]: string} | undefined + public temporaryEnv: Record | undefined public appDirectory: string | undefined constructor({temporaryDirectory}: WorldConstructorParams) { diff --git a/packages/plugin-cloudflare/src/install-cloudflared.test.ts b/packages/plugin-cloudflare/src/install-cloudflared.test.ts index 412cbcbeb5a..b0edfd54302 100644 --- a/packages/plugin-cloudflare/src/install-cloudflared.test.ts +++ b/packages/plugin-cloudflare/src/install-cloudflared.test.ts @@ -3,6 +3,7 @@ import * as fsActions from '@shopify/cli-kit/node/fs' import * as http from '@shopify/cli-kit/node/http' import {beforeEach, describe, expect, test, vi} from 'vitest' import util from 'util' + import {WriteStream} from 'fs' // eslint-disable-next-line no-restricted-imports import * as childProcess from 'child_process' diff --git a/packages/plugin-cloudflare/src/install-cloudflared.ts b/packages/plugin-cloudflare/src/install-cloudflared.ts index d96d3ef8960..37664c67290 100644 --- a/packages/plugin-cloudflare/src/install-cloudflared.ts +++ b/packages/plugin-cloudflare/src/install-cloudflared.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ // Install script for cloudflared, derived from https://github.com/JacobLinCool/node-cloudflared import {basename, dirname, joinPath} from '@shopify/cli-kit/node/path' import {outputDebug} from '@shopify/cli-kit/node/output' @@ -20,25 +19,25 @@ import {execSync, execFileSync} from 'child_process' export const CURRENT_CLOUDFLARE_VERSION = '2024.8.2' const CLOUDFLARE_REPO = `https://github.com/cloudflare/cloudflared/releases/download/${CURRENT_CLOUDFLARE_VERSION}/` -const LINUX_URL: {[key: string]: string} = { +const LINUX_URL: Record = { arm64: 'cloudflared-linux-arm64', arm: 'cloudflared-linux-arm', x64: 'cloudflared-linux-amd64', ia32: 'cloudflared-linux-386', } -const MACOS_URL: {[key: string]: string} = { +const MACOS_URL: Record = { arm64: 'cloudflared-darwin-arm64.tgz', x64: 'cloudflared-darwin-amd64.tgz', } -const WINDOWS_URL: {[key: string]: string} = { +const WINDOWS_URL: Record = { x64: 'cloudflared-windows-amd64.exe', ia32: 'cloudflared-windows-386.exe', arm64: 'cloudflared-windows-amd64.exe', } -const URL: {[key: string]: {[key: string]: string}} = { +const URL: Record> = { linux: LINUX_URL, darwin: MACOS_URL, win32: WINDOWS_URL, diff --git a/packages/plugin-cloudflare/src/tunnel.test.ts b/packages/plugin-cloudflare/src/tunnel.test.ts index d7479a9526f..73b46304406 100644 --- a/packages/plugin-cloudflare/src/tunnel.test.ts +++ b/packages/plugin-cloudflare/src/tunnel.test.ts @@ -2,6 +2,7 @@ import {hookStart} from './tunnel.js' import install from './install-cloudflared.js' import {describe, vi, expect, test, beforeAll} from 'vitest' import {exec} from '@shopify/cli-kit/node/system' + import {Writable} from 'stream' const port = 1234 diff --git a/packages/plugin-cloudflare/src/tunnel.ts b/packages/plugin-cloudflare/src/tunnel.ts index 73b5432e65f..c361923f899 100644 --- a/packages/plugin-cloudflare/src/tunnel.ts +++ b/packages/plugin-cloudflare/src/tunnel.ts @@ -14,6 +14,7 @@ import {joinPath, dirname} from '@shopify/cli-kit/node/path' import {outputDebug} from '@shopify/cli-kit/node/output' import {isUnitTest} from '@shopify/cli-kit/node/context/local' import {BugError} from '@shopify/cli-kit/node/error' + import {Writable} from 'stream' import {fileURLToPath} from 'url' diff --git a/packages/plugin-did-you-mean/src/index.ts b/packages/plugin-did-you-mean/src/index.ts index a7472df62f1..a1909173560 100644 --- a/packages/plugin-did-you-mean/src/index.ts +++ b/packages/plugin-did-you-mean/src/index.ts @@ -1,8 +1,7 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ -import {isAutocorrectEnabled} from './services/conf.js' +import AutocorrectOn from './commands/config/autocorrect/on.js' import AutocorrectOff from './commands/config/autocorrect/off.js' import AutocorrectStatus from './commands/config/autocorrect/status.js' -import AutocorrectOn from './commands/config/autocorrect/on.js' +import {isAutocorrectEnabled} from './services/conf.js' import {Hook} from '@oclif/core' import {bigram} from 'n-gram' import {renderConfirmationPrompt, renderFatalError, renderInfo} from '@shopify/cli-kit/node/ui' @@ -14,7 +13,7 @@ function sanitizeCmd(cmd: string): string { } function relativeScore(commandBigrams: string[], userCommandBigrams: string[]): number { - const map: {[key: string]: number} = {} + const map: Record = {} commandBigrams.forEach((elem) => { // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion map[elem] = map[elem] ? map[elem]! + 1 : 1 diff --git a/packages/theme/src/cli/commands/theme/check.ts b/packages/theme/src/cli/commands/theme/check.ts index 52581848e37..e4f57fda97a 100644 --- a/packages/theme/src/cli/commands/theme/check.ts +++ b/packages/theme/src/cli/commands/theme/check.ts @@ -1,4 +1,4 @@ -import {themeFlags} from '../../flags.js' +import ThemeCommand, {RequiredFlags} from '../../utilities/theme-command.js' import { formatOffensesJson, formatSummary, @@ -12,7 +12,7 @@ import { handleExit, type FailLevel, } from '../../services/check.js' -import ThemeCommand, {RequiredFlags} from '../../utilities/theme-command.js' +import {themeFlags} from '../../flags.js' import {Flags} from '@oclif/core' import {globalFlags} from '@shopify/cli-kit/node/cli' import {outputResult, outputDebug} from '@shopify/cli-kit/node/output' @@ -97,7 +97,7 @@ export default class Check extends ThemeCommand { const environment = flags.environment?.[0] // To support backwards compatibility for legacy configs const isLegacyConfig = flags.config?.startsWith(':') && LegacyIdentifiers.has(flags.config.slice(1)) - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const config = isLegacyConfig ? LegacyIdentifiers.get(flags.config!.slice(1)) : flags.config if (flags.init) { diff --git a/packages/theme/src/cli/commands/theme/console.ts b/packages/theme/src/cli/commands/theme/console.ts index ac86ac094db..298c027461f 100644 --- a/packages/theme/src/cli/commands/theme/console.ts +++ b/packages/theme/src/cli/commands/theme/console.ts @@ -1,6 +1,6 @@ -import {themeFlags} from '../../flags.js' -import ThemeCommand, {RequiredFlags} from '../../utilities/theme-command.js' import {ensureReplEnv, initializeRepl} from '../../services/console.js' +import ThemeCommand, {RequiredFlags} from '../../utilities/theme-command.js' +import {themeFlags} from '../../flags.js' import {globalFlags} from '@shopify/cli-kit/node/cli' import {AdminSession} from '@shopify/cli-kit/node/session' import {Flags} from '@oclif/core' diff --git a/packages/theme/src/cli/commands/theme/delete.ts b/packages/theme/src/cli/commands/theme/delete.ts index 09f0f8a43a9..8a8764730de 100644 --- a/packages/theme/src/cli/commands/theme/delete.ts +++ b/packages/theme/src/cli/commands/theme/delete.ts @@ -1,6 +1,6 @@ -import ThemeCommand from '../../utilities/theme-command.js' -import {themeFlags} from '../../flags.js' import {themesDelete} from '../../services/delete.js' +import {themeFlags} from '../../flags.js' +import ThemeCommand from '../../utilities/theme-command.js' import {Flags} from '@oclif/core' import {globalFlags} from '@shopify/cli-kit/node/cli' import {OutputFlags} from '@oclif/core/interfaces' diff --git a/packages/theme/src/cli/commands/theme/dev.ts b/packages/theme/src/cli/commands/theme/dev.ts index dafb12d03f1..99eb6c25b7f 100644 --- a/packages/theme/src/cli/commands/theme/dev.ts +++ b/packages/theme/src/cli/commands/theme/dev.ts @@ -11,6 +11,7 @@ import {Theme} from '@shopify/cli-kit/node/themes/types' import {recordEvent} from '@shopify/cli-kit/node/analytics' import {AdminSession} from '@shopify/cli-kit/node/session' import {InferredFlags} from '@oclif/core/interfaces' + import type {ErrorOverlayMode, LiveReload} from '../../utilities/theme-environment/types.js' type DevFlags = InferredFlags diff --git a/packages/theme/src/cli/commands/theme/info.ts b/packages/theme/src/cli/commands/theme/info.ts index 56a36833fa3..41f042984df 100644 --- a/packages/theme/src/cli/commands/theme/info.ts +++ b/packages/theme/src/cli/commands/theme/info.ts @@ -1,6 +1,6 @@ -import {themeFlags} from '../../flags.js' -import {fetchThemeInfo, fetchDevInfo, formatThemeInfo} from '../../services/info.js' import ThemeCommand from '../../utilities/theme-command.js' +import {fetchThemeInfo, fetchDevInfo, formatThemeInfo} from '../../services/info.js' +import {themeFlags} from '../../flags.js' import {Flags} from '@oclif/core' import {AdminSession} from '@shopify/cli-kit/node/session' import {AbortError} from '@shopify/cli-kit/node/error' diff --git a/packages/theme/src/cli/commands/theme/init.ts b/packages/theme/src/cli/commands/theme/init.ts index 51dd74c6f19..f04fd9d2016 100644 --- a/packages/theme/src/cli/commands/theme/init.ts +++ b/packages/theme/src/cli/commands/theme/init.ts @@ -1,5 +1,3 @@ -import {themeFlags} from '../../flags.js' -import ThemeCommand from '../../utilities/theme-command.js' import { cloneRepoAndCheckoutLatestTag, cloneRepo, @@ -7,6 +5,8 @@ import { SKELETON_THEME_URL, promptAIInstruction, } from '../../services/init.js' +import ThemeCommand from '../../utilities/theme-command.js' +import {themeFlags} from '../../flags.js' import {Args, Flags} from '@oclif/core' import {globalFlags} from '@shopify/cli-kit/node/cli' import {generateRandomNameForSubdirectory} from '@shopify/cli-kit/node/fs' diff --git a/packages/theme/src/cli/commands/theme/open.ts b/packages/theme/src/cli/commands/theme/open.ts index 67f73bc9f4b..3d3b5cd4f19 100644 --- a/packages/theme/src/cli/commands/theme/open.ts +++ b/packages/theme/src/cli/commands/theme/open.ts @@ -1,6 +1,6 @@ -import ThemeCommand, {RequiredFlags} from '../../utilities/theme-command.js' -import {themeFlags} from '../../flags.js' import {open} from '../../services/open.js' +import {themeFlags} from '../../flags.js' +import ThemeCommand, {RequiredFlags} from '../../utilities/theme-command.js' import {Flags} from '@oclif/core' import {globalFlags} from '@shopify/cli-kit/node/cli' import {AdminSession} from '@shopify/cli-kit/node/session' diff --git a/packages/theme/src/cli/commands/theme/publish.ts b/packages/theme/src/cli/commands/theme/publish.ts index c55a94725a0..dc4c5f89e82 100644 --- a/packages/theme/src/cli/commands/theme/publish.ts +++ b/packages/theme/src/cli/commands/theme/publish.ts @@ -1,6 +1,6 @@ -import ThemeCommand from '../../utilities/theme-command.js' -import {themeFlags} from '../../flags.js' import {publish} from '../../services/publish.js' +import {themeFlags} from '../../flags.js' +import ThemeCommand from '../../utilities/theme-command.js' import {Flags} from '@oclif/core' import {globalFlags} from '@shopify/cli-kit/node/cli' import {OutputFlags} from '@oclif/core/interfaces' diff --git a/packages/theme/src/cli/commands/theme/pull.ts b/packages/theme/src/cli/commands/theme/pull.ts index 77e853ded10..960709e6e32 100644 --- a/packages/theme/src/cli/commands/theme/pull.ts +++ b/packages/theme/src/cli/commands/theme/pull.ts @@ -7,6 +7,7 @@ import {recordTiming} from '@shopify/cli-kit/node/analytics' import {InferredFlags} from '@oclif/core/interfaces' import {AdminSession} from '@shopify/cli-kit/node/session' import {ArgOutput} from '@shopify/cli-kit/node/base-command' + import {Writable} from 'stream' type PullFlags = InferredFlags diff --git a/packages/theme/src/cli/commands/theme/push.ts b/packages/theme/src/cli/commands/theme/push.ts index ea275cd7a95..cbeebbc1d6b 100644 --- a/packages/theme/src/cli/commands/theme/push.ts +++ b/packages/theme/src/cli/commands/theme/push.ts @@ -7,6 +7,7 @@ import {recordTiming} from '@shopify/cli-kit/node/analytics' import {AdminSession} from '@shopify/cli-kit/node/session' import {InferredFlags} from '@oclif/core/interfaces' import {ArgOutput} from '@shopify/cli-kit/node/base-command' + import {Writable} from 'stream' type PushFlags = InferredFlags diff --git a/packages/theme/src/cli/commands/theme/share.ts b/packages/theme/src/cli/commands/theme/share.ts index 49af1a76be0..380abec0a3a 100644 --- a/packages/theme/src/cli/commands/theme/share.ts +++ b/packages/theme/src/cli/commands/theme/share.ts @@ -8,6 +8,7 @@ import {recordTiming} from '@shopify/cli-kit/node/analytics' import {InferredFlags} from '@oclif/core/interfaces' import {AdminSession} from '@shopify/cli-kit/node/session' import {ArgOutput} from '@shopify/cli-kit/node/base-command' + import {Writable} from 'stream' type ShareFlags = InferredFlags diff --git a/packages/theme/src/cli/flags.test.ts b/packages/theme/src/cli/flags.test.ts index fc9c1be8d86..a05754f5d57 100644 --- a/packages/theme/src/cli/flags.test.ts +++ b/packages/theme/src/cli/flags.test.ts @@ -10,7 +10,7 @@ class MockCommand extends Command { ...themeFlags, } - async run(): Promise<{[flag: string]: unknown}> { + async run(): Promise> { const {flags} = await this.parse(MockCommand) return flags } diff --git a/packages/theme/src/cli/services/check.ts b/packages/theme/src/cli/services/check.ts index 210f5177599..3944b5467eb 100644 --- a/packages/theme/src/cli/services/check.ts +++ b/packages/theme/src/cli/services/check.ts @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/no-non-null-assertion */ import {fileExists, readFileSync, writeFile} from '@shopify/cli-kit/node/fs' import {outputResult, outputInfo, outputSuccess} from '@shopify/cli-kit/node/output' import {joinPath} from '@shopify/cli-kit/node/path' @@ -15,9 +14,7 @@ import { } from '@shopify/theme-check-node' import YAML from 'yaml' -interface OffenseMap { - [check: string]: Offense[] -} +type OffenseMap = Record interface TransformedOffense { check: string @@ -317,7 +314,7 @@ export async function outputActiveChecks(root: string, configPath?: string, envi const checkCodes = Object.keys(settings) - const checksList = checkCodes.reduce((acc: {[key: string]: unknown}, checkCode: string) => { + const checksList = checkCodes.reduce((acc: Record, checkCode: string) => { const {severity, enabled, ...additional} = settings[checkCode]! if (!enabled) { return acc diff --git a/packages/theme/src/cli/services/console.test.ts b/packages/theme/src/cli/services/console.test.ts index bb341ddcaa5..2a87309746c 100644 --- a/packages/theme/src/cli/services/console.test.ts +++ b/packages/theme/src/cli/services/console.test.ts @@ -1,9 +1,9 @@ import {ensureReplEnv, initializeRepl} from './console.js' +import {ensureValidPassword} from '../utilities/theme-environment/storefront-password-prompt.js' import { isStorefrontPasswordCorrect, isStorefrontPasswordProtected, } from '../utilities/theme-environment/storefront-session.js' -import {ensureValidPassword} from '../utilities/theme-environment/storefront-password-prompt.js' import {beforeEach, describe, expect, test, vi} from 'vitest' import {AdminSession} from '@shopify/cli-kit/node/session' import {AbortError} from '@shopify/cli-kit/node/error' diff --git a/packages/theme/src/cli/services/delete.ts b/packages/theme/src/cli/services/delete.ts index 3bdd1287c8b..dc86cb21e61 100644 --- a/packages/theme/src/cli/services/delete.ts +++ b/packages/theme/src/cli/services/delete.ts @@ -1,7 +1,7 @@ import {removeDevelopmentTheme} from './local-storage.js' -import {findOrSelectTheme, findThemes} from '../utilities/theme-selector.js' -import {themeComponent, themesComponent} from '../utilities/theme-ui.js' import {DevelopmentThemeManager} from '../utilities/development-theme-manager.js' +import {themeComponent, themesComponent} from '../utilities/theme-ui.js' +import {findOrSelectTheme, findThemes} from '../utilities/theme-selector.js' import {themeDelete} from '@shopify/cli-kit/node/themes/api' import {AdminSession} from '@shopify/cli-kit/node/session' import { diff --git a/packages/theme/src/cli/services/dev.ts b/packages/theme/src/cli/services/dev.ts index 36605935f35..47ad2a174a7 100644 --- a/packages/theme/src/cli/services/dev.ts +++ b/packages/theme/src/cli/services/dev.ts @@ -15,6 +15,7 @@ import {AbortError} from '@shopify/cli-kit/node/error' import {openURL} from '@shopify/cli-kit/node/system' import {debounce} from '@shopify/cli-kit/common/function' import chalk from '@shopify/cli-kit/node/colors' + import readline from 'readline' const DEFAULT_HOST = '127.0.0.1' diff --git a/packages/theme/src/cli/services/duplicate.test.ts b/packages/theme/src/cli/services/duplicate.test.ts index 9072f03c757..99253fcbbba 100644 --- a/packages/theme/src/cli/services/duplicate.test.ts +++ b/packages/theme/src/cli/services/duplicate.test.ts @@ -1,8 +1,8 @@ // packages/theme/src/cli/services/duplicate.test.ts import {duplicate} from './duplicate.js' -import {findThemeById, findOrSelectTheme} from '../utilities/theme-selector.js' -import {themeComponent} from '../utilities/theme-ui.js' import {configureCLIEnvironment} from '../utilities/cli-config.js' +import {themeComponent} from '../utilities/theme-ui.js' +import {findThemeById, findOrSelectTheme} from '../utilities/theme-selector.js' import {themeDuplicate} from '@shopify/cli-kit/node/themes/api' import {renderConfirmationPrompt, renderError, renderSuccess} from '@shopify/cli-kit/node/ui' import {outputResult} from '@shopify/cli-kit/node/output' diff --git a/packages/theme/src/cli/services/duplicate.ts b/packages/theme/src/cli/services/duplicate.ts index 98a786f4315..496a27c7356 100644 --- a/packages/theme/src/cli/services/duplicate.ts +++ b/packages/theme/src/cli/services/duplicate.ts @@ -1,6 +1,6 @@ -import {themeComponent} from '../utilities/theme-ui.js' -import {configureCLIEnvironment} from '../utilities/cli-config.js' import {findOrSelectTheme, findThemeById} from '../utilities/theme-selector.js' +import {configureCLIEnvironment} from '../utilities/cli-config.js' +import {themeComponent} from '../utilities/theme-ui.js' import {renderConfirmationPrompt, renderError, renderSuccess} from '@shopify/cli-kit/node/ui' import {AdminSession} from '@shopify/cli-kit/node/session' import {outputResult} from '@shopify/cli-kit/node/output' diff --git a/packages/theme/src/cli/services/info.test.ts b/packages/theme/src/cli/services/info.test.ts index f7f95b1bc6e..cdecdd5f3d3 100644 --- a/packages/theme/src/cli/services/info.test.ts +++ b/packages/theme/src/cli/services/info.test.ts @@ -1,6 +1,6 @@ import {themeInfoJSON, fetchThemeInfo} from './info.js' -import {findOrSelectTheme} from '../utilities/theme-selector.js' import {DevelopmentThemeManager} from '../utilities/development-theme-manager.js' +import {findOrSelectTheme} from '../utilities/theme-selector.js' import {themePreviewUrl, themeEditorUrl} from '@shopify/cli-kit/node/themes/urls' import {Theme} from '@shopify/cli-kit/node/themes/types' import {describe, vi, test, expect} from 'vitest' diff --git a/packages/theme/src/cli/services/info.ts b/packages/theme/src/cli/services/info.ts index ab7c752cc7d..e61c265f787 100644 --- a/packages/theme/src/cli/services/info.ts +++ b/packages/theme/src/cli/services/info.ts @@ -1,6 +1,6 @@ import {getDevelopmentTheme, getThemeStore} from './local-storage.js' -import {findOrSelectTheme} from '../utilities/theme-selector.js' import {DevelopmentThemeManager} from '../utilities/development-theme-manager.js' +import {findOrSelectTheme} from '../utilities/theme-selector.js' import {platformAndArch} from '@shopify/cli-kit/node/os' import {themeEditorUrl, themePreviewUrl} from '@shopify/cli-kit/node/themes/urls' import {Theme} from '@shopify/cli-kit/node/themes/types' diff --git a/packages/theme/src/cli/services/init.test.ts b/packages/theme/src/cli/services/init.test.ts index 41254efed68..eb79893e22f 100644 --- a/packages/theme/src/cli/services/init.test.ts +++ b/packages/theme/src/cli/services/init.test.ts @@ -15,7 +15,7 @@ vi.mock('@shopify/cli-kit/node/fs', async () => { writeFile: vi.fn(), symlink: vi.fn(), inTemporaryDirectory: vi.fn(async (callback) => { - // eslint-disable-next-line node/no-callback-literal + // eslint-disable-next-line n/no-callback-literal return callback('/tmp') }), } diff --git a/packages/theme/src/cli/services/list.test.ts b/packages/theme/src/cli/services/list.test.ts index 87ba5b4fa33..3d2f2ffe38a 100644 --- a/packages/theme/src/cli/services/list.test.ts +++ b/packages/theme/src/cli/services/list.test.ts @@ -1,5 +1,5 @@ -import {list} from './list.js' import {getDevelopmentTheme} from './local-storage.js' +import {list} from './list.js' import {fetchStoreThemes} from '../utilities/theme-selector/fetch.js' import {Theme} from '@shopify/cli-kit/node/themes/types' import {renderInfo} from '@shopify/cli-kit/node/ui' diff --git a/packages/theme/src/cli/services/list.ts b/packages/theme/src/cli/services/list.ts index bd9809ec7d3..3fe3a94b607 100644 --- a/packages/theme/src/cli/services/list.ts +++ b/packages/theme/src/cli/services/list.ts @@ -1,6 +1,6 @@ import {getDevelopmentTheme} from './local-storage.js' -import {ALLOWED_ROLES, fetchStoreThemes, Role} from '../utilities/theme-selector/fetch.js' import {Filter, FilterProps, filterThemes} from '../utilities/theme-selector/filter.js' +import {ALLOWED_ROLES, fetchStoreThemes, Role} from '../utilities/theme-selector/fetch.js' import {InlineToken, renderInfo} from '@shopify/cli-kit/node/ui' import {AdminSession} from '@shopify/cli-kit/node/session' import {getHostTheme} from '@shopify/cli-kit/node/themes/conf' diff --git a/packages/theme/src/cli/services/local-storage.test.ts b/packages/theme/src/cli/services/local-storage.test.ts index 63f06938187..10468528e67 100644 --- a/packages/theme/src/cli/services/local-storage.test.ts +++ b/packages/theme/src/cli/services/local-storage.test.ts @@ -84,7 +84,7 @@ describe('local-storage', () => { const storage = new LocalStorage({cwd}) setThemeStore('storage-store.myshopify.com', storage) - const results: {[key: string]: string | undefined} = {} + const results: Record = {} await Promise.all([ useThemeStoreContext('store1.myshopify.com', async () => { diff --git a/packages/theme/src/cli/services/local-storage.ts b/packages/theme/src/cli/services/local-storage.ts index 6ad8824a9ef..83785b4fd92 100644 --- a/packages/theme/src/cli/services/local-storage.ts +++ b/packages/theme/src/cli/services/local-storage.ts @@ -9,13 +9,9 @@ export interface ThemeLocalStorageSchema { themeStore: string } -interface DevelopmentThemeLocalStorageSchema { - [themeStore: string]: DevelopmentThemeId -} +type DevelopmentThemeLocalStorageSchema = Record -interface ThemeStorePasswordSchema { - [themeStore: string]: string -} +type ThemeStorePasswordSchema = Record /** Preserves the theme store a command is acting on during multi environment execution */ const themeStoreContext = new AsyncLocalStorage<{store: string}>() diff --git a/packages/theme/src/cli/services/metafields-pull.test.ts b/packages/theme/src/cli/services/metafields-pull.test.ts index d0d9aefbecf..ad449c083b2 100644 --- a/packages/theme/src/cli/services/metafields-pull.test.ts +++ b/packages/theme/src/cli/services/metafields-pull.test.ts @@ -1,8 +1,8 @@ -import {setThemeStore} from './local-storage.js' import {metafieldsPull} from './metafields-pull.js' -import {ensureThemeStore} from '../utilities/theme-store.js' -import {hasRequiredThemeDirectories} from '../utilities/theme-fs.js' +import {setThemeStore} from './local-storage.js' import {ensureDirectoryConfirmed} from '../utilities/theme-ui.js' +import {hasRequiredThemeDirectories} from '../utilities/theme-fs.js' +import {ensureThemeStore} from '../utilities/theme-store.js' import {AdminSession, ensureAuthenticatedThemes} from '@shopify/cli-kit/node/session' import {mockAndCaptureOutput} from '@shopify/cli-kit/node/testing/output' import {metafieldDefinitionsByOwnerType} from '@shopify/cli-kit/node/themes/api' diff --git a/packages/theme/src/cli/services/metafields-pull.ts b/packages/theme/src/cli/services/metafields-pull.ts index d6e296fe512..f0bdf77feae 100644 --- a/packages/theme/src/cli/services/metafields-pull.ts +++ b/packages/theme/src/cli/services/metafields-pull.ts @@ -1,7 +1,7 @@ -import {hasRequiredThemeDirectories} from '../utilities/theme-fs.js' -import {ensureDirectoryConfirmed} from '../utilities/theme-ui.js' -import {ensureThemeStore} from '../utilities/theme-store.js' import {configureCLIEnvironment} from '../utilities/cli-config.js' +import {ensureThemeStore} from '../utilities/theme-store.js' +import {ensureDirectoryConfirmed} from '../utilities/theme-ui.js' +import {hasRequiredThemeDirectories} from '../utilities/theme-fs.js' import {AdminSession, ensureAuthenticatedThemes} from '@shopify/cli-kit/node/session' import {cwd, joinPath} from '@shopify/cli-kit/node/path' import {metafieldDefinitionsByOwnerType} from '@shopify/cli-kit/node/themes/api' diff --git a/packages/theme/src/cli/services/open.test.ts b/packages/theme/src/cli/services/open.test.ts index a6867503dc0..92beee7b16f 100644 --- a/packages/theme/src/cli/services/open.test.ts +++ b/packages/theme/src/cli/services/open.test.ts @@ -1,6 +1,6 @@ import {open} from './open.js' -import {findOrSelectTheme} from '../utilities/theme-selector.js' import {DevelopmentThemeManager} from '../utilities/development-theme-manager.js' +import {findOrSelectTheme} from '../utilities/theme-selector.js' import {Theme} from '@shopify/cli-kit/node/themes/types' import {test, describe, expect, vi, beforeEach} from 'vitest' import {openURL} from '@shopify/cli-kit/node/system' diff --git a/packages/theme/src/cli/services/open.ts b/packages/theme/src/cli/services/open.ts index 741315c85d9..dfa732060f6 100644 --- a/packages/theme/src/cli/services/open.ts +++ b/packages/theme/src/cli/services/open.ts @@ -1,6 +1,6 @@ -import {findOrSelectTheme} from '../utilities/theme-selector.js' -import {themeComponent} from '../utilities/theme-ui.js' import {DevelopmentThemeManager} from '../utilities/development-theme-manager.js' +import {themeComponent} from '../utilities/theme-ui.js' +import {findOrSelectTheme} from '../utilities/theme-selector.js' import {themeEditorUrl, themePreviewUrl} from '@shopify/cli-kit/node/themes/urls' import {openURL} from '@shopify/cli-kit/node/system' import {renderInfo} from '@shopify/cli-kit/node/ui' diff --git a/packages/theme/src/cli/services/package.test.ts b/packages/theme/src/cli/services/package.test.ts index b2250a256b6..04a07462ef4 100644 --- a/packages/theme/src/cli/services/package.test.ts +++ b/packages/theme/src/cli/services/package.test.ts @@ -189,7 +189,7 @@ async function createFiles(structure: string[], directory: string) { async function readArchiveFiles(zipPath: string) { await expect(fileExists(zipPath)).resolves.toBeTruthy() - // eslint-disable-next-line @babel/new-cap + // eslint-disable-next-line new-cap const archive = new StreamZip.async({file: zipPath}) const entries = await archive.entries() const archiveEntries = Object.values(entries) diff --git a/packages/theme/src/cli/services/profile.test.ts b/packages/theme/src/cli/services/profile.test.ts index fdf86ce1af1..9cba4303ebc 100644 --- a/packages/theme/src/cli/services/profile.test.ts +++ b/packages/theme/src/cli/services/profile.test.ts @@ -5,6 +5,7 @@ import {openURL} from '@shopify/cli-kit/node/system' import {vi, describe, expect, beforeEach, test} from 'vitest' import {outputResult} from '@shopify/cli-kit/node/output' import {AbortError} from '@shopify/cli-kit/node/error' + import {readFile} from 'fs/promises' vi.mock('@shopify/cli-kit/node/session') diff --git a/packages/theme/src/cli/services/profile.ts b/packages/theme/src/cli/services/profile.ts index 5aa13179c8a..c246a26a858 100644 --- a/packages/theme/src/cli/services/profile.ts +++ b/packages/theme/src/cli/services/profile.ts @@ -1,8 +1,8 @@ -import {isStorefrontPasswordProtected} from '../utilities/theme-environment/storefront-session.js' -import {ensureValidPassword} from '../utilities/theme-environment/storefront-password-prompt.js' -import {fetchDevServerSession} from '../utilities/theme-environment/dev-server-session.js' -import {render} from '../utilities/theme-environment/storefront-renderer.js' import {resolveAssetPath} from '../utilities/asset-path.js' +import {render} from '../utilities/theme-environment/storefront-renderer.js' +import {fetchDevServerSession} from '../utilities/theme-environment/dev-server-session.js' +import {ensureValidPassword} from '../utilities/theme-environment/storefront-password-prompt.js' +import {isStorefrontPasswordProtected} from '../utilities/theme-environment/storefront-session.js' import {openURL} from '@shopify/cli-kit/node/system' import {joinPath} from '@shopify/cli-kit/node/path' import {AdminSession} from '@shopify/cli-kit/node/session' diff --git a/packages/theme/src/cli/services/publish.ts b/packages/theme/src/cli/services/publish.ts index 7e2da4c1118..008976ce45f 100644 --- a/packages/theme/src/cli/services/publish.ts +++ b/packages/theme/src/cli/services/publish.ts @@ -1,5 +1,5 @@ -import {findOrSelectTheme} from '../utilities/theme-selector.js' import {themeComponent} from '../utilities/theme-ui.js' +import {findOrSelectTheme} from '../utilities/theme-selector.js' import {themePublish} from '@shopify/cli-kit/node/themes/api' import {themePreviewUrl} from '@shopify/cli-kit/node/themes/urls' import {Theme} from '@shopify/cli-kit/node/themes/types' diff --git a/packages/theme/src/cli/services/pull.test.ts b/packages/theme/src/cli/services/pull.test.ts index 24fec497628..ee73344e613 100644 --- a/packages/theme/src/cli/services/pull.test.ts +++ b/packages/theme/src/cli/services/pull.test.ts @@ -7,6 +7,7 @@ import {hasRequiredThemeDirectories, mountThemeFileSystem} from '../utilities/th import {fakeThemeFileSystem} from '../utilities/theme-fs/theme-fs-mock-factory.js' import {downloadTheme} from '../utilities/theme-downloader.js' import {themeComponent, ensureDirectoryConfirmed} from '../utilities/theme-ui.js' + import {mkTmpDir, rmdir} from '@shopify/cli-kit/node/fs' import {buildTheme} from '@shopify/cli-kit/node/themes/factories' import {ensureAuthenticatedThemes} from '@shopify/cli-kit/node/session' @@ -14,6 +15,7 @@ import {fetchChecksums} from '@shopify/cli-kit/node/themes/api' import {insideGitDirectory, isClean} from '@shopify/cli-kit/node/git' import {test, describe, expect, vi, beforeEach} from 'vitest' import {dirname, joinPath} from '@shopify/cli-kit/node/path' + import {fileURLToPath} from 'node:url' vi.mock('../utilities/theme-selector.js') diff --git a/packages/theme/src/cli/services/pull.ts b/packages/theme/src/cli/services/pull.ts index 677fbb5355e..85e00d135a9 100644 --- a/packages/theme/src/cli/services/pull.ts +++ b/packages/theme/src/cli/services/pull.ts @@ -14,6 +14,7 @@ import {glob} from '@shopify/cli-kit/node/fs' import {cwd} from '@shopify/cli-kit/node/path' import {insideGitDirectory, isClean} from '@shopify/cli-kit/node/git' import {recordTiming} from '@shopify/cli-kit/node/analytics' + import {Writable} from 'stream' interface PullOptions { diff --git a/packages/theme/src/cli/services/push.test.ts b/packages/theme/src/cli/services/push.test.ts index 2d3d4b27068..5991dd00376 100644 --- a/packages/theme/src/cli/services/push.test.ts +++ b/packages/theme/src/cli/services/push.test.ts @@ -1,11 +1,11 @@ -import {createOrSelectTheme, push, PushFlags} from './push.js' -import {PullFlags} from './pull.js' import {setDevelopmentTheme} from './local-storage.js' -import {uploadTheme} from '../utilities/theme-uploader.js' -import {ensureThemeStore} from '../utilities/theme-store.js' -import {findOrSelectTheme} from '../utilities/theme-selector.js' -import {runThemeCheck} from '../commands/theme/check.js' +import {PullFlags} from './pull.js' +import {createOrSelectTheme, push, PushFlags} from './push.js' import {mountThemeFileSystem} from '../utilities/theme-fs.js' +import {runThemeCheck} from '../commands/theme/check.js' +import {findOrSelectTheme} from '../utilities/theme-selector.js' +import {ensureThemeStore} from '../utilities/theme-store.js' +import {uploadTheme} from '../utilities/theme-uploader.js' import {buildTheme} from '@shopify/cli-kit/node/themes/factories' import {test, describe, vi, expect, beforeEach} from 'vitest' import {themeCreate, fetchTheme, themePublish} from '@shopify/cli-kit/node/themes/api' diff --git a/packages/theme/src/cli/services/push.ts b/packages/theme/src/cli/services/push.ts index fde42ac60cd..863050b70a7 100644 --- a/packages/theme/src/cli/services/push.ts +++ b/packages/theme/src/cli/services/push.ts @@ -26,6 +26,7 @@ import {LIVE_THEME_ROLE, promptThemeName, UNPUBLISHED_THEME_ROLE} from '@shopify import {AbortError} from '@shopify/cli-kit/node/error' import {Severity} from '@shopify/theme-check-node' import {recordError, recordTiming} from '@shopify/cli-kit/node/analytics' + import {Writable} from 'stream' interface PushOptions { @@ -299,7 +300,7 @@ function handleJsonOutput(theme: Theme, session: AdminSession, results: Map = {} for (const [key, result] of results.entries()) { if (!result.success && result.errors?.asset) { errors[key] = result.errors.asset diff --git a/packages/theme/src/cli/services/rename.ts b/packages/theme/src/cli/services/rename.ts index c45cc4ce16c..51052756cd7 100644 --- a/packages/theme/src/cli/services/rename.ts +++ b/packages/theme/src/cli/services/rename.ts @@ -1,5 +1,5 @@ -import {findOrSelectTheme} from '../utilities/theme-selector.js' import {themeComponent} from '../utilities/theme-ui.js' +import {findOrSelectTheme} from '../utilities/theme-selector.js' import {themeUpdate} from '@shopify/cli-kit/node/themes/api' import {AdminSession} from '@shopify/cli-kit/node/session' import {renderSuccess} from '@shopify/cli-kit/node/ui' diff --git a/packages/theme/src/cli/utilities/asset-checksum.test.ts b/packages/theme/src/cli/utilities/asset-checksum.test.ts index a6fc14791b0..aa056b876ea 100644 --- a/packages/theme/src/cli/utilities/asset-checksum.test.ts +++ b/packages/theme/src/cli/utilities/asset-checksum.test.ts @@ -2,6 +2,7 @@ import {calculateChecksum, rejectGeneratedStaticAssets} from './asset-checksum.j import {readThemeFile} from './theme-fs.js' import {describe, expect, test} from 'vitest' import {joinPath, dirname} from '@shopify/cli-kit/node/path' + import {fileURLToPath} from 'node:url' describe('asset-checksum', () => { diff --git a/packages/theme/src/cli/utilities/cli-config.ts b/packages/theme/src/cli/utilities/cli-config.ts index a803eb6617d..88e811a9a88 100644 --- a/packages/theme/src/cli/utilities/cli-config.ts +++ b/packages/theme/src/cli/utilities/cli-config.ts @@ -14,7 +14,6 @@ interface CLIConfigOptions { */ export function configureCLIEnvironment(options: CLIConfigOptions): void { if (options.verbose) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion process.env[globalFlags.verbose.env!] = 'true' } diff --git a/packages/theme/src/cli/utilities/development-theme-manager.test.ts b/packages/theme/src/cli/utilities/development-theme-manager.test.ts index 3914b350491..b6a029249ce 100644 --- a/packages/theme/src/cli/utilities/development-theme-manager.test.ts +++ b/packages/theme/src/cli/utilities/development-theme-manager.test.ts @@ -19,7 +19,7 @@ describe('DevelopmentThemeManager', () => { const existingId = 200 const newThemeId = 201 const onlyLocallyExistingId = 404 - const themeTestDatabase: {[id: number]: Theme | undefined} = { + const themeTestDatabase: Record = { [existingId]: {id: existingId} as Theme, [onlyLocallyExistingId]: undefined, } diff --git a/packages/theme/src/cli/utilities/log-request-line.test.ts b/packages/theme/src/cli/utilities/log-request-line.test.ts index fe60018c59f..a69f63a9526 100644 --- a/packages/theme/src/cli/utilities/log-request-line.test.ts +++ b/packages/theme/src/cli/utilities/log-request-line.test.ts @@ -2,6 +2,7 @@ import {shouldLog} from './log-request-line.js' import {createEvent} from 'h3' import {describe, test, expect} from 'vitest' import {IncomingMessage, ServerResponse} from 'node:http' + import {Socket} from 'node:net' function createH3Event(method = 'GET', path = '/', headers = {}) { diff --git a/packages/theme/src/cli/utilities/log-request-line.ts b/packages/theme/src/cli/utilities/log-request-line.ts index 4c0f35d6e96..3373c2cd6c8 100644 --- a/packages/theme/src/cli/utilities/log-request-line.ts +++ b/packages/theme/src/cli/utilities/log-request-line.ts @@ -1,9 +1,9 @@ -/* eslint-disable @typescript-eslint/unbound-method */ import {EXTENSION_CDN_PREFIX, VANITY_CDN_PREFIX} from './theme-environment/proxy.js' import {timestampDateFormat} from '../constants.js' import {outputContent, outputInfo, outputToken} from '@shopify/cli-kit/node/output' import {H3Event} from 'h3' import {extname} from '@shopify/cli-kit/node/path' + import type {DevServerContext} from './theme-environment/types.js' const CHARACTER_TRUNCATION_LIMIT = 80 diff --git a/packages/theme/src/cli/utilities/notifier.test.ts b/packages/theme/src/cli/utilities/notifier.test.ts index a055e450da1..e3ad842a599 100644 --- a/packages/theme/src/cli/utilities/notifier.test.ts +++ b/packages/theme/src/cli/utilities/notifier.test.ts @@ -1,6 +1,7 @@ import {Notifier} from './notifier.js' import {vi, describe, expect, test} from 'vitest' import {outputWarn} from '@shopify/cli-kit/node/output' + import fs from 'fs/promises' vi.mock('fs/promises') diff --git a/packages/theme/src/cli/utilities/repl/evaluator.test.ts b/packages/theme/src/cli/utilities/repl/evaluator.test.ts index d0e745348fc..6eac7e8a1b9 100644 --- a/packages/theme/src/cli/utilities/repl/evaluator.test.ts +++ b/packages/theme/src/cli/utilities/repl/evaluator.test.ts @@ -1,6 +1,6 @@ import {evaluate, EvaluationConfig} from './evaluator.js' -import {DevServerSession} from '../theme-environment/types.js' import {render} from '../theme-environment/storefront-renderer.js' +import {DevServerSession} from '../theme-environment/types.js' import {beforeEach, describe, expect, test, vi} from 'vitest' import {outputContent, outputInfo, outputToken} from '@shopify/cli-kit/node/output' import {AbortError} from '@shopify/cli-kit/node/error' @@ -219,7 +219,7 @@ function createMockResponse({ }: { status: number text: string - headers?: {[key: string]: string} + headers?: Record }) { return { status, diff --git a/packages/theme/src/cli/utilities/repl/repl.test.ts b/packages/theme/src/cli/utilities/repl/repl.test.ts index ebe605ce990..8cc9aea5c76 100644 --- a/packages/theme/src/cli/utilities/repl/repl.test.ts +++ b/packages/theme/src/cli/utilities/repl/repl.test.ts @@ -4,6 +4,7 @@ import {presentValue} from './presenter.js' import {DevServerSession} from '../theme-environment/types.js' import {describe, expect, test, vi} from 'vitest' import {outputInfo} from '@shopify/cli-kit/node/output' + import {createInterface} from 'readline' vi.mock('@shopify/cli-kit/node/output') diff --git a/packages/theme/src/cli/utilities/repl/repl.ts b/packages/theme/src/cli/utilities/repl/repl.ts index d8ab76a370b..090a48fd9c3 100644 --- a/packages/theme/src/cli/utilities/repl/repl.ts +++ b/packages/theme/src/cli/utilities/repl/repl.ts @@ -3,6 +3,7 @@ import {presentValue} from './presenter.js' import {DevServerSession} from '../theme-environment/types.js' import {AbortError} from '@shopify/cli-kit/node/error' import {outputDebug, outputInfo} from '@shopify/cli-kit/node/output' + import {createInterface, Interface} from 'readline' export const DELIMITER_WARNING = diff --git a/packages/theme/src/cli/utilities/theme-command.test.ts b/packages/theme/src/cli/utilities/theme-command.test.ts index 15a71e6aae9..30dbb1f5c84 100644 --- a/packages/theme/src/cli/utilities/theme-command.test.ts +++ b/packages/theme/src/cli/utilities/theme-command.test.ts @@ -8,6 +8,7 @@ import {fileExistsSync} from '@shopify/cli-kit/node/fs' import {AbortError} from '@shopify/cli-kit/node/error' import {resolvePath} from '@shopify/cli-kit/node/path' import {renderConcurrent, renderConfirmationPrompt, renderError, renderWarning} from '@shopify/cli-kit/node/ui' + import type {Writable} from 'stream' vi.mock('@shopify/cli-kit/node/session') diff --git a/packages/theme/src/cli/utilities/theme-command.ts b/packages/theme/src/cli/utilities/theme-command.ts index 52dc6171993..e5c8cb6ed53 100644 --- a/packages/theme/src/cli/utilities/theme-command.ts +++ b/packages/theme/src/cli/utilities/theme-command.ts @@ -1,6 +1,7 @@ import {ensureThemeStore} from './theme-store.js' import {configurationFileName} from '../constants.js' import {useThemeStoreContext} from '../services/local-storage.js' + import {hashString} from '@shopify/cli-kit/node/crypto' import {Input} from '@oclif/core/interfaces' import Command, {ArgOutput, FlagOutput, noDefaultsOptions} from '@shopify/cli-kit/node/base-command' @@ -20,11 +21,10 @@ import {addPublicMetadata, addSensitiveMetadata} from '@shopify/cli-kit/node/met import {cwd, joinPath, resolvePath} from '@shopify/cli-kit/node/path' import {fileExistsSync} from '@shopify/cli-kit/node/fs' import {normalizeStoreFqdn} from '@shopify/cli-kit/node/context/fqdn' + import type {Writable} from 'stream' -interface FlagValues { - [key: string]: boolean | string | string[] | number | undefined -} +type FlagValues = Record interface ValidEnvironment { environment: EnvironmentName flags: FlagValues diff --git a/packages/theme/src/cli/utilities/theme-downloader.test.ts b/packages/theme/src/cli/utilities/theme-downloader.test.ts index bde58d971d6..530b7434f88 100644 --- a/packages/theme/src/cli/utilities/theme-downloader.test.ts +++ b/packages/theme/src/cli/utilities/theme-downloader.test.ts @@ -1,5 +1,5 @@ -import {downloadTheme} from './theme-downloader.js' import {fakeThemeFileSystem} from './theme-fs/theme-fs-mock-factory.js' +import {downloadTheme} from './theme-downloader.js' import {fetchThemeAssets} from '@shopify/cli-kit/node/themes/api' import {Checksum, ThemeAsset} from '@shopify/cli-kit/node/themes/types' import {test, describe, expect, vi} from 'vitest' diff --git a/packages/theme/src/cli/utilities/theme-downloader.ts b/packages/theme/src/cli/utilities/theme-downloader.ts index fae80deb311..b20dfd824ed 100644 --- a/packages/theme/src/cli/utilities/theme-downloader.ts +++ b/packages/theme/src/cli/utilities/theme-downloader.ts @@ -4,6 +4,7 @@ import {AdminSession} from '@shopify/cli-kit/node/session' import {fetchThemeAssets} from '@shopify/cli-kit/node/themes/api' import {ThemeFileSystem, Theme, Checksum, ThemeAsset} from '@shopify/cli-kit/node/themes/types' import {renderTasks} from '@shopify/cli-kit/node/ui' + import {Writable} from 'stream' interface DownloadOptions { diff --git a/packages/theme/src/cli/utilities/theme-environment/cookies.ts b/packages/theme/src/cli/utilities/theme-environment/cookies.ts index 8888209c04a..c7b5768a6c3 100644 --- a/packages/theme/src/cli/utilities/theme-environment/cookies.ts +++ b/packages/theme/src/cli/utilities/theme-environment/cookies.ts @@ -1,5 +1,5 @@ export function parseCookies(cookies: string) { - const cookiesRecord: {[key: string]: string} = {} + const cookiesRecord: Record = {} cookies.split(';').forEach((cookie) => { const parts = cookie.match(/(.*?)=(.*)$/) ?? [] @@ -15,7 +15,7 @@ export function parseCookies(cookies: string) { return cookiesRecord } -export function serializeCookies(cookies: {[key: string]: string}) { +export function serializeCookies(cookies: Record) { return Object.entries(cookies) .map(([key, value]) => `${key}=${value}`) .join('; ') diff --git a/packages/theme/src/cli/utilities/theme-environment/dev-server-session.test.ts b/packages/theme/src/cli/utilities/theme-environment/dev-server-session.test.ts index ed40429c3df..d9f28dc5961 100644 --- a/packages/theme/src/cli/utilities/theme-environment/dev-server-session.test.ts +++ b/packages/theme/src/cli/utilities/theme-environment/dev-server-session.test.ts @@ -1,10 +1,10 @@ +import {getStorefrontSessionCookies, ShopifyEssentialError} from './storefront-session.js' import { abortOnMissingRequiredFile, getStorefrontSessionCookiesWithVerification, initializeDevServerSession, fetchDevServerSession, } from './dev-server-session.js' -import {getStorefrontSessionCookies, ShopifyEssentialError} from './storefront-session.js' import {ensureAuthenticatedStorefront, ensureAuthenticatedThemes} from '@shopify/cli-kit/node/session' import {fetchThemeAssets, themeDelete} from '@shopify/cli-kit/node/themes/api' import {describe, expect, test, vi, beforeEach} from 'vitest' diff --git a/packages/theme/src/cli/utilities/theme-environment/dev-server-session.ts b/packages/theme/src/cli/utilities/theme-environment/dev-server-session.ts index 39911f23eb3..7e2192f3a39 100644 --- a/packages/theme/src/cli/utilities/theme-environment/dev-server-session.ts +++ b/packages/theme/src/cli/utilities/theme-environment/dev-server-session.ts @@ -1,6 +1,6 @@ -import {buildBaseStorefrontUrl} from './storefront-renderer.js' -import {getStorefrontSessionCookies, ShopifyEssentialError} from './storefront-session.js' import {DevServerSession} from './types.js' +import {getStorefrontSessionCookies, ShopifyEssentialError} from './storefront-session.js' +import {buildBaseStorefrontUrl} from './storefront-renderer.js' import {fetchThemeAssets} from '@shopify/cli-kit/node/themes/api' import {AbortError} from '@shopify/cli-kit/node/error' import {outputDebug, outputContent, outputToken} from '@shopify/cli-kit/node/output' @@ -94,7 +94,7 @@ export async function getStorefrontSessionCookiesWithVerification( adminSession: AdminSession, storefrontToken: string, storefrontPassword?: string, -): Promise<{[key: string]: string}> { +): Promise> { try { return await getStorefrontSessionCookies(storeUrl, adminSession.storeFqdn, themeId, storefrontPassword, { 'X-Shopify-Shop': adminSession.storeFqdn, diff --git a/packages/theme/src/cli/utilities/theme-environment/hot-reload/server.test.ts b/packages/theme/src/cli/utilities/theme-environment/hot-reload/server.test.ts index 441e46408d6..3d2905a369b 100644 --- a/packages/theme/src/cli/utilities/theme-environment/hot-reload/server.test.ts +++ b/packages/theme/src/cli/utilities/theme-environment/hot-reload/server.test.ts @@ -13,11 +13,15 @@ import {fakeThemeFileSystem} from '../../theme-fs/theme-fs-mock-factory.js' import {render} from '../storefront-renderer.js' import {emptyThemeExtFileSystem} from '../../theme-fs-empty.js' import {describe, test, expect, vi, beforeEach} from 'vitest' + import {createEvent} from 'h3' import * as output from '@shopify/cli-kit/node/output' + import {IncomingMessage, ServerResponse} from 'node:http' import {Socket} from 'node:net' + import type {DevServerContext} from '../types.js' + import type {Theme, ThemeFSEventName, ThemeAsset} from '@shopify/cli-kit/node/themes/types' vi.mock('../storefront-renderer.js') @@ -464,7 +468,7 @@ describe('getUpdatedFileParts', () => { // -- Test utilities -- -function createH3Event(url: string, headers?: {[key: string]: string}) { +function createH3Event(url: string, headers?: Record) { const data: string[] = [] const decoder = new TextDecoder() @@ -515,7 +519,6 @@ function createTestContext(options?: {files?: [string, string][]}) { .catch(() => {}) } - // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain const handler = addEventListenerSpy.mock.calls.find(([eventName]) => eventName === event)?.[1]! handler({ diff --git a/packages/theme/src/cli/utilities/theme-environment/hot-reload/server.ts b/packages/theme/src/cli/utilities/theme-environment/hot-reload/server.ts index 60173e5eb7f..4912224f6e1 100644 --- a/packages/theme/src/cli/utilities/theme-environment/hot-reload/server.ts +++ b/packages/theme/src/cli/utilities/theme-environment/hot-reload/server.ts @@ -19,7 +19,9 @@ import {extname, joinPath} from '@shopify/cli-kit/node/path' import {parseJSON} from '@shopify/theme-check-node' import {readFile} from '@shopify/cli-kit/node/fs' import {recordError, recordEvent} from '@shopify/cli-kit/node/analytics' + import EventEmitter from 'node:events' + import type { HotReloadEvent, HotReloadFileEvent, @@ -27,6 +29,7 @@ import type { HotReloadFullEvent, } from '@shopify/theme-hot-reload' import type {Theme, ThemeAsset, ThemeFSEventPayload} from '@shopify/cli-kit/node/themes/types' + import type {DevServerContext} from '../types.js' // --- Section tag content cache --- @@ -45,9 +48,7 @@ export const fileDetailsCache = new Map() /** Store existing section names and types read from JSON files in the project */ const sectionNamesByFile = new Map() -interface SectionGroup { - [key: string]: {type: string} -} +type SectionGroup = Record function saveSectionsFromJson(fileKey: string, content: string) { const maybeJson = parseJSON(content, null, true) @@ -74,7 +75,7 @@ function needsTemplateUpdate(fileKey: string) { * If a route is passed, it will filter out the templates that are not related to the route. */ export function getInMemoryTemplates(ctx: DevServerContext, currentRoute?: string, locale?: string) { - const inMemoryTemplates: {[key: string]: string} = {} + const inMemoryTemplates: Record = {} const jsonTemplateRE = /^templates\/.+\.json$/ const filterTemplate = currentRoute @@ -242,7 +243,7 @@ export function getHotReloadHandler(theme: Theme, ctx: DevServerContext): EventH return } - const replaceTemplates: {[key: string]: string} = {} + const replaceTemplates: Record = {} if (sectionId) { const inMemoryTemplateFiles = ctx.localThemeFileSystem.unsyncedFileKeys diff --git a/packages/theme/src/cli/utilities/theme-environment/html.test.ts b/packages/theme/src/cli/utilities/theme-environment/html.test.ts index fdfedf958c4..1ff7800914e 100644 --- a/packages/theme/src/cli/utilities/theme-environment/html.test.ts +++ b/packages/theme/src/cli/utilities/theme-environment/html.test.ts @@ -5,6 +5,7 @@ import {emptyThemeExtFileSystem, emptyThemeFileSystem} from '../theme-fs-empty.j import {createEvent} from 'h3' import {describe, expect, test, vi} from 'vitest' import {Theme} from '@shopify/cli-kit/node/themes/types' + import {IncomingMessage, ServerResponse} from 'node:http' import {Socket} from 'node:net' diff --git a/packages/theme/src/cli/utilities/theme-environment/html.ts b/packages/theme/src/cli/utilities/theme-environment/html.ts index 6bb2f056096..c8a68462ed0 100644 --- a/packages/theme/src/cli/utilities/theme-environment/html.ts +++ b/packages/theme/src/cli/utilities/theme-environment/html.ts @@ -1,16 +1,17 @@ -import {getProxyStorefrontHeaders, patchRenderingResponse, proxyStorefrontRequest} from './proxy.js' -import {getInMemoryTemplates, handleHotReloadScriptInjection} from './hot-reload/server.js' -import {render} from './storefront-renderer.js' import {getErrorPage} from './hot-reload/error-page.js' -import {getExtensionInMemoryTemplates} from '../theme-ext-environment/theme-ext-server.js' -import {logRequestLine} from '../log-request-line.js' +import {render} from './storefront-renderer.js' +import {getInMemoryTemplates, handleHotReloadScriptInjection} from './hot-reload/server.js' +import {getProxyStorefrontHeaders, patchRenderingResponse, proxyStorefrontRequest} from './proxy.js' import {extractFetchErrorInfo} from '../errors.js' +import {logRequestLine} from '../log-request-line.js' +import {getExtensionInMemoryTemplates} from '../theme-ext-environment/theme-ext-server.js' import {defineEventHandler, getCookie, type H3Event, type EventHandler} from 'h3' import {renderError, renderFatalError} from '@shopify/cli-kit/node/ui' import {outputDebug} from '@shopify/cli-kit/node/output' import {AbortError} from '@shopify/cli-kit/node/error' import {recordEvent} from '@shopify/cli-kit/node/analytics' import type {Theme} from '@shopify/cli-kit/node/themes/types' + import type {DevServerContext} from './types.js' /** Tracks the number of consecutive theme ID mismatch redirects */ diff --git a/packages/theme/src/cli/utilities/theme-environment/local-assets.ts b/packages/theme/src/cli/utilities/theme-environment/local-assets.ts index 2c3f676fdc3..0ef0ae490f1 100644 --- a/packages/theme/src/cli/utilities/theme-environment/local-assets.ts +++ b/packages/theme/src/cli/utilities/theme-environment/local-assets.ts @@ -1,6 +1,6 @@ -import {injectCdnProxy} from './proxy.js' -import {parseServerEvent} from './server-utils.js' import {getLiquidTagContent} from './liquid-tag-content.js' +import {parseServerEvent} from './server-utils.js' +import {injectCdnProxy} from './proxy.js' import {lookupMimeType} from '@shopify/cli-kit/node/mimes' import {defineEventHandler, H3Event, serveStatic, setResponseHeader, sendError, createError} from 'h3' import {joinPath} from '@shopify/cli-kit/node/path' @@ -75,7 +75,6 @@ function findLocalFile(event: H3Event, ctx: DevServerContext) { const file = fileSystem.files.get(fileKey) const isUnsynced = fileSystem.unsyncedFileKeys.has(fileKey) - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing if (file || isUnsynced) { return {file, isUnsynced, fileKey} } diff --git a/packages/theme/src/cli/utilities/theme-environment/proxy.test.ts b/packages/theme/src/cli/utilities/theme-environment/proxy.test.ts index dd954934a91..36693898e52 100644 --- a/packages/theme/src/cli/utilities/theme-environment/proxy.test.ts +++ b/packages/theme/src/cli/utilities/theme-environment/proxy.test.ts @@ -8,7 +8,9 @@ import { import {describe, test, expect} from 'vitest' import {createEvent} from 'h3' import {IncomingMessage, ServerResponse} from 'node:http' + import {Socket} from 'node:net' + import type {DevServerContext} from './types.js' function createH3Event(method = 'GET', path = '/', headers = {}) { diff --git a/packages/theme/src/cli/utilities/theme-environment/proxy.ts b/packages/theme/src/cli/utilities/theme-environment/proxy.ts index 9f08555eb51..debfc8e6d94 100644 --- a/packages/theme/src/cli/utilities/theme-environment/proxy.ts +++ b/packages/theme/src/cli/utilities/theme-environment/proxy.ts @@ -1,7 +1,7 @@ -/* eslint-disable @typescript-eslint/no-dynamic-delete */ -import {buildCookies} from './storefront-renderer.js' import {cleanHeader, defaultHeaders} from './storefront-utils.js' +import {buildCookies} from './storefront-renderer.js' import {logRequestLine} from '../log-request-line.js' + import {createFetchError, extractFetchErrorInfo} from '../errors.js' import {renderWarning} from '@shopify/cli-kit/node/ui' import {defineEventHandler, getRequestHeaders, getRequestWebStream, getRequestIP, type H3Event} from 'h3' @@ -277,7 +277,7 @@ function patchProxiedResponseHeaders(ctx: DevServerContext, rawResponse: Respons * Filters headers to forward to SFR. */ export function getProxyStorefrontHeaders(event: H3Event) { - const proxyRequestHeaders = getRequestHeaders(event) as {[key: string]: string} + const proxyRequestHeaders = getRequestHeaders(event) as Record for (const headerKey of HOP_BY_HOP_HEADERS) { delete proxyRequestHeaders[headerKey] @@ -319,7 +319,7 @@ export function proxyStorefrontRequest(event: H3Event, ctx: DevServerContext): P const headers = getProxyStorefrontHeaders(event) const body = getRequestWebStream(event) - const baseHeaders: {[key: string]: string} = { + const baseHeaders: Record = { ...headers, ...defaultHeaders(), referer: url.origin, diff --git a/packages/theme/src/cli/utilities/theme-environment/remote-theme-watcher.test.ts b/packages/theme/src/cli/utilities/theme-environment/remote-theme-watcher.test.ts index a37cbeb83c5..53ad80b13a9 100644 --- a/packages/theme/src/cli/utilities/theme-environment/remote-theme-watcher.test.ts +++ b/packages/theme/src/cli/utilities/theme-environment/remote-theme-watcher.test.ts @@ -1,6 +1,6 @@ -import {reconcileJsonFiles} from './theme-reconciliation.js' -import {reconcileAndPollThemeEditorChanges} from './remote-theme-watcher.js' import {pollThemeEditorChanges} from './theme-polling.js' +import {reconcileAndPollThemeEditorChanges} from './remote-theme-watcher.js' +import {reconcileJsonFiles} from './theme-reconciliation.js' import {fakeThemeFileSystem} from '../theme-fs/theme-fs-mock-factory.js' import {fetchChecksums} from '@shopify/cli-kit/node/themes/api' import {buildTheme} from '@shopify/cli-kit/node/themes/factories' diff --git a/packages/theme/src/cli/utilities/theme-environment/remote-theme-watcher.ts b/packages/theme/src/cli/utilities/theme-environment/remote-theme-watcher.ts index 7e129d20348..7c300586ee3 100644 --- a/packages/theme/src/cli/utilities/theme-environment/remote-theme-watcher.ts +++ b/packages/theme/src/cli/utilities/theme-environment/remote-theme-watcher.ts @@ -1,5 +1,5 @@ -import {pollThemeEditorChanges} from './theme-polling.js' import {reconcileJsonFiles} from './theme-reconciliation.js' +import {pollThemeEditorChanges} from './theme-polling.js' import {outputDebug} from '@shopify/cli-kit/node/output' import {AdminSession} from '@shopify/cli-kit/node/session' import {Checksum, Theme, ThemeFileSystem} from '@shopify/cli-kit/node/themes/types' diff --git a/packages/theme/src/cli/utilities/theme-environment/storefront-password-prompt.test.ts b/packages/theme/src/cli/utilities/theme-environment/storefront-password-prompt.test.ts index d451cfcb55c..952d5b2c1ba 100644 --- a/packages/theme/src/cli/utilities/theme-environment/storefront-password-prompt.test.ts +++ b/packages/theme/src/cli/utilities/theme-environment/storefront-password-prompt.test.ts @@ -7,6 +7,7 @@ import { setStorefrontPassword, } from '../../services/local-storage.js' import {ensureThemeStore} from '../theme-store.js' + import {renderTextPrompt} from '@shopify/cli-kit/node/ui' import {describe, beforeEach, vi, test, expect} from 'vitest' diff --git a/packages/theme/src/cli/utilities/theme-environment/storefront-password-prompt.ts b/packages/theme/src/cli/utilities/theme-environment/storefront-password-prompt.ts index 29e8af5ad35..7f176157510 100644 --- a/packages/theme/src/cli/utilities/theme-environment/storefront-password-prompt.ts +++ b/packages/theme/src/cli/utilities/theme-environment/storefront-password-prompt.ts @@ -7,6 +7,7 @@ import { } from '../../services/local-storage.js' import {ensureThemeStore} from '../theme-store.js' import {renderTextPrompt, TokenItem} from '@shopify/cli-kit/node/ui' + import {storePasswordPage} from '@shopify/cli-kit/node/themes/urls' export async function ensureValidPassword(password: string | undefined, store: string) { diff --git a/packages/theme/src/cli/utilities/theme-environment/storefront-renderer.ts b/packages/theme/src/cli/utilities/theme-environment/storefront-renderer.ts index ed66b4e8ae0..5b86f641265 100644 --- a/packages/theme/src/cli/utilities/theme-environment/storefront-renderer.ts +++ b/packages/theme/src/cli/utilities/theme-environment/storefront-renderer.ts @@ -1,6 +1,6 @@ -import {parseCookies, serializeCookies} from './cookies.js' -import {cleanHeader, defaultHeaders, storefrontReplaceTemplatesParams} from './storefront-utils.js' import {DevServerSession, DevServerRenderContext} from './types.js' +import {cleanHeader, defaultHeaders, storefrontReplaceTemplatesParams} from './storefront-utils.js' +import {parseCookies, serializeCookies} from './cookies.js' import {createFetchError} from '../errors.js' import {outputDebug} from '@shopify/cli-kit/node/output' import {AdminSession} from '@shopify/cli-kit/node/session' @@ -87,7 +87,7 @@ async function buildStandardHeaders(session: DevServerSession, context: DevServe async function buildThemeAccessHeaders(session: DevServerSession, context: DevServerRenderContext) { const cookies = await buildCookies(session, context) const storefrontToken = session.storefrontToken - const filteredHeaders: {[key: string]: string} = {} + const filteredHeaders: Record = {} const filterKeys = ['ACCEPT', 'CONTENT-TYPE', 'CONTENT-LENGTH'] for (const [key, value] of Object.entries(context.headers)) { diff --git a/packages/theme/src/cli/utilities/theme-environment/storefront-session.test.ts b/packages/theme/src/cli/utilities/theme-environment/storefront-session.test.ts index 89284f28ee0..71df8d9b369 100644 --- a/packages/theme/src/cli/utilities/theme-environment/storefront-session.test.ts +++ b/packages/theme/src/cli/utilities/theme-environment/storefront-session.test.ts @@ -343,7 +343,7 @@ describe('Storefront API', () => { function response(mock: { status: number url?: string - headers?: {[key: string]: string} + headers?: Record text?: () => Promise }) { const setCookieHeader = (mock.headers ?? {})['set-cookie'] ?? '' diff --git a/packages/theme/src/cli/utilities/theme-environment/storefront-session.ts b/packages/theme/src/cli/utilities/theme-environment/storefront-session.ts index ad7aafea2b2..e477b1b2ad8 100644 --- a/packages/theme/src/cli/utilities/theme-environment/storefront-session.ts +++ b/packages/theme/src/cli/utilities/theme-environment/storefront-session.ts @@ -1,5 +1,5 @@ -import {parseCookies, serializeCookies} from './cookies.js' import {defaultHeaders} from './storefront-utils.js' +import {parseCookies, serializeCookies} from './cookies.js' import {shopifyFetch, Response} from '@shopify/cli-kit/node/http' import {AbortError} from '@shopify/cli-kit/node/error' import {outputDebug} from '@shopify/cli-kit/node/output' @@ -54,9 +54,9 @@ export async function getStorefrontSessionCookies( storeFqdn: string, themeId: string, password?: string, - headers: {[key: string]: string} = {}, -): Promise<{[key: string]: string}> { - const cookieRecord: {[key: string]: string} = {} + headers: Record = {}, +): Promise> { + const cookieRecord: Record = {} const shopifyEssential = await sessionEssentialCookie(storeUrl, themeId, headers) const storeOrigin = prependHttps(storeFqdn) @@ -83,12 +83,7 @@ export async function getStorefrontSessionCookies( return {...cookieRecord, ...additionalCookies} } -async function sessionEssentialCookie( - storeUrl: string, - themeId: string, - headers: {[key: string]: string}, - retries = 1, -) { +async function sessionEssentialCookie(storeUrl: string, themeId: string, headers: Record, retries = 1) { const params = new URLSearchParams({ preview_theme_id: themeId, _fd: '0', @@ -145,8 +140,8 @@ async function enrichSessionWithStorefrontPassword( storeUrl: string, storeOrigin: string, password: string, - headers: {[key: string]: string}, -): Promise<{[key: string]: string}> { + headers: Record, +): Promise> { const params = new URLSearchParams({password}) const response = await shopifyFetch(`${storeUrl}/password`, { @@ -172,7 +167,7 @@ async function enrichSessionWithStorefrontPassword( const storefrontDigest = getCookie(setCookies, 'storefront_digest') const newShopifyEssential = getCookie(setCookies, '_shopify_essential') - const result: {[key: string]: string} = {} + const result: Record = {} if (storefrontDigest) { result.storefront_digest = storefrontDigest diff --git a/packages/theme/src/cli/utilities/theme-environment/storefront-utils.ts b/packages/theme/src/cli/utilities/theme-environment/storefront-utils.ts index c18b30a9be2..e70b63131d5 100644 --- a/packages/theme/src/cli/utilities/theme-environment/storefront-utils.ts +++ b/packages/theme/src/cli/utilities/theme-environment/storefront-utils.ts @@ -27,7 +27,7 @@ export function defaultHeaders() { } } -export function cleanHeader(headers: {[key: string]: string}): {[key: string]: string} { +export function cleanHeader(headers: Record): Record { // Force the use of the 'Cookie' key if consumers also provide the 'cookie' key delete headers.cookie delete headers.authorization diff --git a/packages/theme/src/cli/utilities/theme-environment/theme-environment.test.ts b/packages/theme/src/cli/utilities/theme-environment/theme-environment.test.ts index 02508a5ee67..d82d5b34503 100644 --- a/packages/theme/src/cli/utilities/theme-environment/theme-environment.test.ts +++ b/packages/theme/src/cli/utilities/theme-environment/theme-environment.test.ts @@ -6,12 +6,14 @@ import {hotReloadScriptId} from './hot-reload/server.js' import {uploadTheme} from '../theme-uploader.js' import {fakeThemeFileSystem} from '../theme-fs/theme-fs-mock-factory.js' import {emptyThemeExtFileSystem} from '../theme-fs-empty.js' + import {DEVELOPMENT_THEME_ROLE} from '@shopify/cli-kit/node/themes/utils' import {describe, expect, test, vi, beforeEach, afterEach} from 'vitest' import {buildTheme} from '@shopify/cli-kit/node/themes/factories' import {createEvent} from 'h3' import * as output from '@shopify/cli-kit/node/output' import {fetchChecksums} from '@shopify/cli-kit/node/themes/api' + import {IncomingMessage, ServerResponse} from 'node:http' import {Socket} from 'node:net' @@ -211,7 +213,7 @@ describe('setupDevServer', () => { const html = String.raw const decoder = new TextDecoder() - const createH3Event = (options: {url: string; headers?: {[key: string]: string}}) => { + const createH3Event = (options: {url: string; headers?: Record}) => { const req = new IncomingMessage(new Socket()) req.url = options.url if (options.headers) req.headers = options.headers @@ -221,7 +223,7 @@ describe('setupDevServer', () => { const dispatchEvent = async ( url: string, - headers?: {[key: string]: string}, + headers?: Record, ): Promise<{res: ServerResponse; status: number; body: string | Buffer}> => { const event = createH3Event({url, headers}) const {res} = event.node diff --git a/packages/theme/src/cli/utilities/theme-environment/theme-environment.ts b/packages/theme/src/cli/utilities/theme-environment/theme-environment.ts index 34bbd14d710..2660bd1acb4 100644 --- a/packages/theme/src/cli/utilities/theme-environment/theme-environment.ts +++ b/packages/theme/src/cli/utilities/theme-environment/theme-environment.ts @@ -7,10 +7,14 @@ import {uploadTheme} from '../theme-uploader.js' import {renderTasksToStdErr} from '../theme-ui.js' import {renderThrownError} from '../errors.js' import {promiseWithResolvers} from '../../polyfills/promiseWithResolvers.js' + import {createApp, defineEventHandler, defineLazyEventHandler, toNodeListener, handleCors} from 'h3' import {fetchChecksums} from '@shopify/cli-kit/node/themes/api' + import {createServer} from 'node:http' + import type {Checksum, Theme} from '@shopify/cli-kit/node/themes/types' + import type {DevServerContext} from './types.js' export function setupDevServer(theme: Theme, ctx: DevServerContext) { diff --git a/packages/theme/src/cli/utilities/theme-environment/theme-polling.ts b/packages/theme/src/cli/utilities/theme-environment/theme-polling.ts index c8de4126687..03c325abdcc 100644 --- a/packages/theme/src/cli/utilities/theme-environment/theme-polling.ts +++ b/packages/theme/src/cli/utilities/theme-environment/theme-polling.ts @@ -1,6 +1,6 @@ -import {MAX_GRAPHQL_THEME_FILES, timestampDateFormat} from '../../constants.js' -import {batchedRequests} from '../batching.js' import {renderThrownError} from '../errors.js' +import {batchedRequests} from '../batching.js' +import {MAX_GRAPHQL_THEME_FILES, timestampDateFormat} from '../../constants.js' import {Checksum, Theme, ThemeFileSystem} from '@shopify/cli-kit/node/themes/types' import {fetchChecksums, fetchThemeAssets} from '@shopify/cli-kit/node/themes/api' import {outputDebug, outputInfo, outputContent, outputToken} from '@shopify/cli-kit/node/output' diff --git a/packages/theme/src/cli/utilities/theme-environment/theme-reconciliation.test.ts b/packages/theme/src/cli/utilities/theme-environment/theme-reconciliation.test.ts index 0083c373b40..3a885a2abdd 100644 --- a/packages/theme/src/cli/utilities/theme-environment/theme-reconciliation.test.ts +++ b/packages/theme/src/cli/utilities/theme-environment/theme-reconciliation.test.ts @@ -1,5 +1,5 @@ -import {reconcileJsonFiles} from './theme-reconciliation.js' import {REMOTE_STRATEGY, LOCAL_STRATEGY} from './remote-theme-watcher.js' +import {reconcileJsonFiles} from './theme-reconciliation.js' import {fakeThemeFileSystem} from '../theme-fs/theme-fs-mock-factory.js' import {deleteThemeAssets, fetchThemeAssets} from '@shopify/cli-kit/node/themes/api' import {buildTheme} from '@shopify/cli-kit/node/themes/factories' diff --git a/packages/theme/src/cli/utilities/theme-environment/theme-reconciliation.ts b/packages/theme/src/cli/utilities/theme-environment/theme-reconciliation.ts index 2d5079938b3..d678aa06526 100644 --- a/packages/theme/src/cli/utilities/theme-environment/theme-reconciliation.ts +++ b/packages/theme/src/cli/utilities/theme-environment/theme-reconciliation.ts @@ -1,6 +1,6 @@ import {REMOTE_STRATEGY, LOCAL_STRATEGY} from './remote-theme-watcher.js' -import {batchedRequests} from '../batching.js' import {MAX_GRAPHQL_THEME_FILES} from '../../constants.js' +import {batchedRequests} from '../batching.js' import {outputDebug} from '@shopify/cli-kit/node/output' import {AdminSession} from '@shopify/cli-kit/node/session' import {deleteThemeAssets, fetchThemeAssets} from '@shopify/cli-kit/node/themes/api' diff --git a/packages/theme/src/cli/utilities/theme-environment/types.ts b/packages/theme/src/cli/utilities/theme-environment/types.ts index 39d4bdee5e1..9b689c7daf8 100644 --- a/packages/theme/src/cli/utilities/theme-environment/types.ts +++ b/packages/theme/src/cli/utilities/theme-environment/types.ts @@ -35,7 +35,7 @@ export interface DevServerSession extends AdminSession { * crucial for determining the theme used during * rendering. */ - sessionCookies: {[key: string]: string} + sessionCookies: Record /** * Refreshes the current session, ensuring any tokens and session cookies @@ -182,15 +182,15 @@ export interface DevServerRenderContext { /** * Headers to be used in the rendering request. */ - headers: {[key: string]: string} + headers: Record /** * Custom content to be replaced in the theme during rendering. */ - replaceTemplates?: {[key: string]: string} + replaceTemplates?: Record /** * Custom content to be replaced during rendering. */ - replaceExtensionTemplates?: {[key: string]: string} + replaceExtensionTemplates?: Record } diff --git a/packages/theme/src/cli/utilities/theme-ext-environment/theme-ext-fs.ts b/packages/theme/src/cli/utilities/theme-ext-environment/theme-ext-fs.ts index 4f21a324ab4..bb168f4984f 100644 --- a/packages/theme/src/cli/utilities/theme-ext-environment/theme-ext-fs.ts +++ b/packages/theme/src/cli/utilities/theme-ext-environment/theme-ext-fs.ts @@ -5,7 +5,9 @@ import {glob} from '@shopify/cli-kit/node/fs' import {joinPath, relativePath} from '@shopify/cli-kit/node/path' import {sleep} from '@shopify/cli-kit/node/system' import {buildThemeAsset} from '@shopify/cli-kit/node/themes/factories' + import EventEmitter from 'node:events' + import type { ThemeAsset, ThemeExtensionFileSystem, @@ -50,7 +52,6 @@ export function mountThemeExtensionFileSystem(root: string): ThemeExtensionFileS const fileKey = relativePath(root, filePath) const contentPromise = read(fileKey).then(() => { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const file = files.get(fileKey)! unsyncedFileKeys.add(file.key) diff --git a/packages/theme/src/cli/utilities/theme-ext-environment/theme-ext-server.ts b/packages/theme/src/cli/utilities/theme-ext-environment/theme-ext-server.ts index 5ed6a0d420f..0ff73ab674d 100644 --- a/packages/theme/src/cli/utilities/theme-ext-environment/theme-ext-server.ts +++ b/packages/theme/src/cli/utilities/theme-ext-environment/theme-ext-server.ts @@ -7,8 +7,11 @@ import {getHotReloadHandler, triggerHotReload} from '../theme-environment/hot-re import {emptyThemeFileSystem} from '../theme-fs-empty.js' import {initializeDevServerSession} from '../theme-environment/dev-server-session.js' import {createApp, toNodeListener} from 'h3' + import {AdminSession} from '@shopify/cli-kit/node/session' + import {createServer} from 'node:http' + import type {Theme, ThemeFSEventPayload} from '@shopify/cli-kit/node/themes/types' interface DevelopmentServerInstance { @@ -114,7 +117,7 @@ export async function setupInMemoryTemplateWatcher(theme: Theme, ctx: DevServerC } export function getExtensionInMemoryTemplates(ctx: DevServerContext) { - const replaceExtTemplates: {[key: string]: string} = {} + const replaceExtTemplates: Record = {} const fileSystem = ctx.localThemeExtensionFileSystem for (const key of fileSystem.unsyncedFileKeys) { diff --git a/packages/theme/src/cli/utilities/theme-fs.test.ts b/packages/theme/src/cli/utilities/theme-fs.test.ts index 3c498383acf..ac981cbf5ce 100644 --- a/packages/theme/src/cli/utilities/theme-fs.test.ts +++ b/packages/theme/src/cli/utilities/theme-fs.test.ts @@ -19,6 +19,7 @@ import {renderError} from '@shopify/cli-kit/node/ui' import {Operation, type Checksum, type ThemeAsset} from '@shopify/cli-kit/node/themes/types' import {dirname, joinPath} from '@shopify/cli-kit/node/path' import {AdminSession} from '@shopify/cli-kit/node/session' + import EventEmitter from 'events' import {fileURLToPath} from 'node:url' diff --git a/packages/theme/src/cli/utilities/theme-fs.ts b/packages/theme/src/cli/utilities/theme-fs.ts index 967856e61e0..8b236845ec3 100644 --- a/packages/theme/src/cli/utilities/theme-fs.ts +++ b/packages/theme/src/cli/utilities/theme-fs.ts @@ -12,8 +12,10 @@ import {outputContent, outputDebug, outputInfo, outputToken, outputWarn} from '@ import {buildThemeAsset} from '@shopify/cli-kit/node/themes/factories' import {AdminSession} from '@shopify/cli-kit/node/session' import {bulkUploadThemeAssets, deleteThemeAssets} from '@shopify/cli-kit/node/themes/api' + import EventEmitter from 'node:events' import {fileURLToPath} from 'node:url' + import type { ThemeFileSystem, ThemeFileSystemOptions, diff --git a/packages/theme/src/cli/utilities/theme-selector.test.ts b/packages/theme/src/cli/utilities/theme-selector.test.ts index 4acb517e603..a1caddff2be 100644 --- a/packages/theme/src/cli/utilities/theme-selector.test.ts +++ b/packages/theme/src/cli/utilities/theme-selector.test.ts @@ -1,5 +1,5 @@ -import {fetchStoreThemes} from './theme-selector/fetch.js' import {findOrSelectTheme, findThemeById, findThemes, newThemeOption} from './theme-selector.js' +import {fetchStoreThemes} from './theme-selector/fetch.js' import {getDevelopmentTheme} from '../services/local-storage.js' import {test, describe, vi, expect} from 'vitest' import {renderAutocompletePrompt} from '@shopify/cli-kit/node/ui' diff --git a/packages/theme/src/cli/utilities/theme-selector.ts b/packages/theme/src/cli/utilities/theme-selector.ts index feefa366110..c77e1c2d6f2 100644 --- a/packages/theme/src/cli/utilities/theme-selector.ts +++ b/packages/theme/src/cli/utilities/theme-selector.ts @@ -1,5 +1,5 @@ -import {fetchStoreThemes} from './theme-selector/fetch.js' import {Filter, FilterProps, filterThemes} from './theme-selector/filter.js' +import {fetchStoreThemes} from './theme-selector/fetch.js' import {getDevelopmentTheme} from '../services/local-storage.js' import {renderAutocompletePrompt} from '@shopify/cli-kit/node/ui' import {AdminSession} from '@shopify/cli-kit/node/session' @@ -40,7 +40,6 @@ export async function findOrSelectTheme(session: AdminSession, options: FindOrSe const store = session.storeFqdn if (filter.any()) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion return filterThemes(store, themes, filter)[0]! } diff --git a/packages/theme/src/cli/utilities/theme-store.ts b/packages/theme/src/cli/utilities/theme-store.ts index b3cbc905bdd..4fa695ed625 100644 --- a/packages/theme/src/cli/utilities/theme-store.ts +++ b/packages/theme/src/cli/utilities/theme-store.ts @@ -1,5 +1,5 @@ -import {themeFlags} from '../flags.js' import {getThemeStore, setThemeStore} from '../services/local-storage.js' +import {themeFlags} from '../flags.js' import {recordError} from '@shopify/cli-kit/node/analytics' import {AbortError} from '@shopify/cli-kit/node/error' import {outputContent, outputToken} from '@shopify/cli-kit/node/output' diff --git a/packages/theme/src/cli/utilities/theme-uploader.test.ts b/packages/theme/src/cli/utilities/theme-uploader.test.ts index 5b5b3fae062..41f92a35254 100644 --- a/packages/theme/src/cli/utilities/theme-uploader.test.ts +++ b/packages/theme/src/cli/utilities/theme-uploader.test.ts @@ -1,3 +1,5 @@ +import {renderTasksToStdErr} from './theme-ui.js' +import {fakeThemeFileSystem} from './theme-fs/theme-fs-mock-factory.js' import { MAX_BATCH_BYTESIZE, MAX_BATCH_FILE_COUNT, @@ -6,8 +8,6 @@ import { uploadTheme, updateUploadErrors, } from './theme-uploader.js' -import {fakeThemeFileSystem} from './theme-fs/theme-fs-mock-factory.js' -import {renderTasksToStdErr} from './theme-ui.js' import {bulkUploadThemeAssets, deleteThemeAssets} from '@shopify/cli-kit/node/themes/api' import {Result, Checksum, Key, ThemeAsset, Operation} from '@shopify/cli-kit/node/themes/types' import {beforeEach, describe, expect, test, vi} from 'vitest' diff --git a/packages/theme/src/cli/utilities/theme-uploader.ts b/packages/theme/src/cli/utilities/theme-uploader.ts index aa860ef5c3e..2b56cb04357 100644 --- a/packages/theme/src/cli/utilities/theme-uploader.ts +++ b/packages/theme/src/cli/utilities/theme-uploader.ts @@ -9,6 +9,7 @@ import {AssetParams, bulkUploadThemeAssets, deleteThemeAssets} from '@shopify/cl import {Task} from '@shopify/cli-kit/node/ui' import {outputDebug} from '@shopify/cli-kit/node/output' import {recordEvent} from '@shopify/cli-kit/node/analytics' + import {Writable} from 'stream' interface UploadOptions { @@ -378,7 +379,7 @@ function calculateLocalChecksums(localThemeFileSystem: ThemeFileSystem): Checksu localThemeFileSystem.files.forEach((file, key) => { // Text files: use UTF-8 byte count // Binary files: use base64 length - const size = file.value ? Buffer.byteLength(file.value, 'utf8') : file.attachment?.length ?? 0 + const size = file.value ? Buffer.byteLength(file.value, 'utf8') : (file.attachment?.length ?? 0) checksums.push({ key, diff --git a/packages/ui-extensions-dev-console/src/App.tsx b/packages/ui-extensions-dev-console/src/App.tsx index 6915e72c191..2ef8902066b 100644 --- a/packages/ui-extensions-dev-console/src/App.tsx +++ b/packages/ui-extensions-dev-console/src/App.tsx @@ -1,11 +1,11 @@ -import React from 'react' -import {I18nContext, I18nManager} from '@shopify/react-i18n' -import {ExtensionServerProvider, isValidSurface} from '@shopify/ui-extensions-server-kit' import {Layout} from '@/foundation/Layout' import {Routes} from '@/foundation/Routes' import {Toast} from '@/foundation/Toast' import {Theme} from '@/foundation/Theme' import {ModalContainer} from '@/foundation/ModalContainer' +import {ExtensionServerProvider, isValidSurface} from '@shopify/ui-extensions-server-kit' +import {I18nContext, I18nManager} from '@shopify/react-i18n' +import React from 'react' function getConnectionUrl() { if (import.meta.env.VITE_CONNECTION_URL) { diff --git a/packages/ui-extensions-dev-console/src/components/Button/Button.tsx b/packages/ui-extensions-dev-console/src/components/Button/Button.tsx index 936459564db..daff96a5ed9 100644 --- a/packages/ui-extensions-dev-console/src/components/Button/Button.tsx +++ b/packages/ui-extensions-dev-console/src/components/Button/Button.tsx @@ -1,7 +1,7 @@ import * as styles from './Button.module.scss' import {Icon, IconProps} from '../Icon/Icon.js' -import React from 'react' import {classNames} from '@/utilities/css' +import React from 'react' interface ButtonProps extends React.HTMLProps { icon?: { diff --git a/packages/ui-extensions-dev-console/src/components/Icon/Icon.tsx b/packages/ui-extensions-dev-console/src/components/Icon/Icon.tsx index 422362f7541..65883124fc5 100644 --- a/packages/ui-extensions-dev-console/src/components/Icon/Icon.tsx +++ b/packages/ui-extensions-dev-console/src/components/Icon/Icon.tsx @@ -1,7 +1,7 @@ import styles from './Icon.module.scss' import {VisuallyHidden} from '../VisuallyHidden/VisuallyHidden.js' -import React from 'react' import {classNames} from '@/utilities/css' +import React from 'react' export interface IconProps { /** The SVG contents to display in the icon (icons should fit in a 20 × 20 pixel viewBox) */ diff --git a/packages/ui-extensions-dev-console/src/components/IconButton/IconButton.tsx b/packages/ui-extensions-dev-console/src/components/IconButton/IconButton.tsx index 97aa1ca7c50..d1fc0620fab 100644 --- a/packages/ui-extensions-dev-console/src/components/IconButton/IconButton.tsx +++ b/packages/ui-extensions-dev-console/src/components/IconButton/IconButton.tsx @@ -1,7 +1,7 @@ import * as styles from './IconButton.module.scss' -import React from 'react' import {Icon, IconProps} from '@/components/Icon' import {classNames} from '@/utilities/css' +import React from 'react' interface IconButtonProps extends React.HTMLProps, IconProps { type: 'button' | 'submit' | 'reset' | undefined diff --git a/packages/ui-extensions-dev-console/src/components/Modal/Modal.tsx b/packages/ui-extensions-dev-console/src/components/Modal/Modal.tsx index 4ddc961bff2..2a7aa4453be 100644 --- a/packages/ui-extensions-dev-console/src/components/Modal/Modal.tsx +++ b/packages/ui-extensions-dev-console/src/components/Modal/Modal.tsx @@ -1,10 +1,9 @@ -import {Dialog, Header, Backdrop} from './components' import styles from './Modal.module.scss' - +import {Dialog, Header, Backdrop} from './components' +import {ModalContainerId} from '@/foundation/ModalContainer' import {TransitionGroup} from 'react-transition-group' import React, {useState} from 'react' import {createPortal} from 'react-dom' -import {ModalContainerId} from '@/foundation/ModalContainer' export interface ModalProps { /** Whether the modal is open or not */ diff --git a/packages/ui-extensions-dev-console/src/components/Modal/components/Backdrop/Backdrop.tsx b/packages/ui-extensions-dev-console/src/components/Modal/components/Backdrop/Backdrop.tsx index fc5cde15f5c..83b46432b0a 100644 --- a/packages/ui-extensions-dev-console/src/components/Modal/components/Backdrop/Backdrop.tsx +++ b/packages/ui-extensions-dev-console/src/components/Modal/components/Backdrop/Backdrop.tsx @@ -18,7 +18,7 @@ export function Backdrop({onClick, setClosing}: Props) { return ( <> - {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */} + {/* The backdrop is intentionally click-only without keyboard interaction */}
) diff --git a/packages/ui-extensions-dev-console/src/components/Modal/components/Dialog/Dialog.tsx b/packages/ui-extensions-dev-console/src/components/Modal/components/Dialog/Dialog.tsx index 54f009f79c8..1d06b5a2cba 100644 --- a/packages/ui-extensions-dev-console/src/components/Modal/components/Dialog/Dialog.tsx +++ b/packages/ui-extensions-dev-console/src/components/Modal/components/Dialog/Dialog.tsx @@ -1,9 +1,8 @@ import styles from './Dialog.module.scss' - -import React, {useRef, SetStateAction, Dispatch, useLayoutEffect, useCallback} from 'react' -import {CSSTransition} from 'react-transition-group' import {focusFirstFocusableNode} from '@/utilities/focus' import {classNames} from '@/utilities/css' +import React, {useRef, SetStateAction, Dispatch, useLayoutEffect, useCallback} from 'react' +import {CSSTransition} from 'react-transition-group' enum Key { Escape = 27, diff --git a/packages/ui-extensions-dev-console/src/components/Modal/components/Header/components/CloseButton/CloseButton.tsx b/packages/ui-extensions-dev-console/src/components/Modal/components/Header/components/CloseButton/CloseButton.tsx index 9fe6f61e1ff..b284da64113 100644 --- a/packages/ui-extensions-dev-console/src/components/Modal/components/Header/components/CloseButton/CloseButton.tsx +++ b/packages/ui-extensions-dev-console/src/components/Modal/components/Header/components/CloseButton/CloseButton.tsx @@ -1,8 +1,8 @@ import en from './translations/en.json' +import {IconButton} from '@/components/IconButton/IconButton' import React from 'react' import {XIcon} from '@shopify/polaris-icons' import {useI18n} from '@shopify/react-i18n' -import {IconButton} from '@/components/IconButton/IconButton' interface CloseButtonProps { pressed?: boolean diff --git a/packages/ui-extensions-dev-console/src/components/Tooltip/Tooltip.tsx b/packages/ui-extensions-dev-console/src/components/Tooltip/Tooltip.tsx index ec9b93171ec..1d7363ce3fd 100644 --- a/packages/ui-extensions-dev-console/src/components/Tooltip/Tooltip.tsx +++ b/packages/ui-extensions-dev-console/src/components/Tooltip/Tooltip.tsx @@ -1,7 +1,7 @@ import styles from './Tooltip.module.css' import {TooltipPopover} from './TooltipPopover' -import React, {useRef, useState} from 'react' import {classNames} from '@/utilities/css' +import React, {useRef, useState} from 'react' interface TooltipProps { children: JSX.Element | string diff --git a/packages/ui-extensions-dev-console/src/foundation/Layout/Layout.tsx b/packages/ui-extensions-dev-console/src/foundation/Layout/Layout.tsx index a30d687647f..021c1aa65f7 100644 --- a/packages/ui-extensions-dev-console/src/foundation/Layout/Layout.tsx +++ b/packages/ui-extensions-dev-console/src/foundation/Layout/Layout.tsx @@ -1,9 +1,9 @@ -import * as styles from './Layout.module.scss' import en from './translations/en.json' +import * as styles from './Layout.module.scss' +import {isAppPreview} from '@/utilities/app-preview' import React from 'react' import {WrenchIcon} from '@shopify/polaris-icons' import {useI18n} from '@shopify/react-i18n' -import {isAppPreview} from '@/utilities/app-preview' interface Props { children: React.ReactNode diff --git a/packages/ui-extensions-dev-console/src/foundation/Routes/Routes.tsx b/packages/ui-extensions-dev-console/src/foundation/Routes/Routes.tsx index cd699ee4d63..6dd59db7199 100644 --- a/packages/ui-extensions-dev-console/src/foundation/Routes/Routes.tsx +++ b/packages/ui-extensions-dev-console/src/foundation/Routes/Routes.tsx @@ -1,6 +1,6 @@ +import {Extensions} from '@/sections/Extensions' import React from 'react' import {BrowserRouter, Routes as ReactRouterRoutes, Route} from 'react-router-dom' -import {Extensions} from '@/sections/Extensions' export function Routes() { return ( diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/Extensions.test.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/Extensions.test.tsx index 4dca57e796b..fa60f35ef18 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/Extensions.test.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/Extensions.test.tsx @@ -1,11 +1,11 @@ -import {Extensions} from './Extensions.js' - import {AppHomeRow, ExtensionRow} from './components' + +import {Extensions} from './Extensions.js' +import {DefaultProviders} from 'tests/DefaultProviders' import React from 'react' import {ExtensionServerClient} from '@shopify/ui-extensions-server-kit' import {mockExtension} from '@shopify/ui-extensions-server-kit/testing' import {render, withProviders} from '@shopify/ui-extensions-test-utils' -import {DefaultProviders} from 'tests/DefaultProviders' vi.mock('./components', () => ({ ExtensionRow: () => null, diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/Extensions.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/Extensions.tsx index b1202fe42f6..f0ecc3439a1 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/Extensions.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/Extensions.tsx @@ -5,10 +5,11 @@ import en from './translations/en.json' import {useExtensions} from './hooks/useExtensions' import {useExtensionServerOptions} from './hooks/useExtensionServerOptions' import {useApp} from './hooks/useApp' -import {useI18n} from '@shopify/react-i18n' -import React from 'react' + import {isEmbedded} from '@/utilities/embedded' import {isAppPreview} from '@/utilities/app-preview' +import React from 'react' +import {useI18n} from '@shopify/react-i18n' export function Extensions() { const [i18n] = useI18n({ diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/AppHomeRow/AppHomeRow.test.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/AppHomeRow/AppHomeRow.test.tsx index 6eaaefd577e..657b90ba29d 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/AppHomeRow/AppHomeRow.test.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/AppHomeRow/AppHomeRow.test.tsx @@ -1,12 +1,12 @@ import {AppHomeRow} from '.' import en from './translations/en.json' import {PreviewLink, QRCodeModal} from '..' -import React from 'react' - import {DefaultProviders} from 'tests/DefaultProviders' import {mockI18n} from 'tests/mock-i18n' -import {render, withProviders} from '@shopify/ui-extensions-test-utils' import {Button} from '@/components' +import React from 'react' + +import {render, withProviders} from '@shopify/ui-extensions-test-utils' vi.mock('..', () => ({ NotApplicable: () => null, diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/AppHomeRow/AppHomeRow.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/AppHomeRow/AppHomeRow.tsx index 49a1bc6996f..372263caec2 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/AppHomeRow/AppHomeRow.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/AppHomeRow/AppHomeRow.tsx @@ -1,12 +1,13 @@ -import * as styles from './AppHomeRow.module.scss' import en from './translations/en.json' - +import * as styles from './AppHomeRow.module.scss' import {NotApplicable, PreviewLink, QRCodeModal, Row} from '..' import {useApp} from '../../hooks/useApp' import {useExtensionServerOptions} from '../../hooks/useExtensionServerOptions.js' -import {useI18n} from '@shopify/react-i18n' -import React, {useState} from 'react' + import {Button} from '@/components' +import React, {useState} from 'react' + +import {useI18n} from '@shopify/react-i18n' export function AppHomeRow() { const [showModal, setShowModal] = useState(false) diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/ExtensionRow.test.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/ExtensionRow.test.tsx index 4e59cde442b..33f4ac94bc0 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/ExtensionRow.test.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/ExtensionRow.test.tsx @@ -1,13 +1,13 @@ import {ExtensionRow} from '.' import en from './translations/en.json' import {QRCodeModal} from '..' -import React from 'react' - import {DefaultProviders} from 'tests/DefaultProviders' import {mockI18n} from 'tests/mock-i18n' +import {Button} from '@/components' +import React from 'react' + import {render, withProviders} from '@shopify/ui-extensions-test-utils' import {mockExtension} from '@shopify/ui-extensions-server-kit/testing' -import {Button} from '@/components' vi.mock('./components', () => ({ PreviewLinks: () => null, diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/ExtensionRow.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/ExtensionRow.tsx index ff7b080afd5..af65c52f23c 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/ExtensionRow.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/ExtensionRow.tsx @@ -1,13 +1,12 @@ -import * as styles from './ExtensionRow.module.scss' -import en from './translations/en.json' - import {PreviewLinks} from './components' +import en from './translations/en.json' +import * as styles from './ExtensionRow.module.scss' import {QRCodeModal, Row, Status} from '..' import {useExtension} from '../../hooks/useExtension' +import {Button} from '@/components/Button' import React, {useState} from 'react' import {useI18n} from '@shopify/react-i18n' import {ExtensionPayload, ExtensionPoint, isUIExtension} from '@shopify/ui-extensions-server-kit' -import {Button} from '@/components/Button' interface Props { uuid: ExtensionPayload['uuid'] diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/components/PreviewLinks/PreviewLinks.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/components/PreviewLinks/PreviewLinks.tsx index e6d0fc8ee0a..04cdd4e103a 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/components/PreviewLinks/PreviewLinks.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/ExtensionRow/components/PreviewLinks/PreviewLinks.tsx @@ -1,10 +1,10 @@ -import * as styles from './PreviewLinks.module.scss' import en from './translations/en.json' +import * as styles from './PreviewLinks.module.scss' import {NotApplicable, PreviewLink} from '../../..' +import {classNames} from '@/utilities/css' import React from 'react' import {ExtensionPayload} from '@shopify/ui-extensions-server-kit' import {useI18n} from '@shopify/react-i18n' -import {classNames} from '@/utilities/css' interface Props { extension: ExtensionPayload diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/PreviewLink/PreviewLink.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/PreviewLink/PreviewLink.tsx index c1c42962157..85e222e265e 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/PreviewLink/PreviewLink.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/PreviewLink/PreviewLink.tsx @@ -1,12 +1,12 @@ -import * as styles from './PreviewLink.module.scss' import en from './translations/en.json' +import * as styles from './PreviewLink.module.scss' import {useNavigate} from '../../hooks/useNavigate.js' +import {IconButton} from '@/components/IconButton' +import {isEmbedded} from '@/utilities/embedded' import React from 'react' import {useI18n} from '@shopify/react-i18n' import {ClipboardIcon} from '@shopify/polaris-icons' import {toast} from 'react-toastify' -import {IconButton} from '@/components/IconButton' -import {isEmbedded} from '@/utilities/embedded' interface Props { rootUrl: string diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/QRCodeModal/QRCodeModal.test.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/QRCodeModal/QRCodeModal.test.tsx index d5f925a0af7..2b55bbb11a4 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/QRCodeModal/QRCodeModal.test.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/QRCodeModal/QRCodeModal.test.tsx @@ -1,12 +1,12 @@ -import en from './translations/en.json' import {QRCodeModal} from './QRCodeModal' +import en from './translations/en.json' +import {mockI18n} from 'tests/mock-i18n' +import {DefaultProviders} from 'tests/DefaultProviders' +import {Modal} from '@/components/Modal' import React from 'react' import QRCode from 'qrcode.react' import {mockApp, mockExtension} from '@shopify/ui-extensions-server-kit/testing' import {render, withProviders} from '@shopify/ui-extensions-test-utils' -import {mockI18n} from 'tests/mock-i18n' -import {DefaultProviders} from 'tests/DefaultProviders' -import {Modal} from '@/components/Modal' vi.spyOn(HTMLCanvasElement.prototype, 'getContext').mockReturnValue(null) diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/QRCodeModal/QRCodeModal.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/QRCodeModal/QRCodeModal.tsx index 007e062e9b2..088f5bd503d 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/QRCodeModal/QRCodeModal.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/QRCodeModal/QRCodeModal.tsx @@ -1,6 +1,8 @@ -import en from './translations/en.json' import * as styles from './QRCodeModal.module.scss' +import en from './translations/en.json' import {useApp} from '../../hooks/useApp' +import {Modal, ModalProps} from '@/components/Modal' +import {IconButton} from '@/components/IconButton' import React, {useCallback, useMemo} from 'react' import {useI18n} from '@shopify/react-i18n' import copyToClipboard from 'copy-to-clipboard' @@ -8,8 +10,6 @@ import QRCode from 'qrcode.react' import {toast} from 'react-toastify' import {Surface} from '@shopify/ui-extensions-server-kit' import {ClipboardIcon} from '@shopify/polaris-icons' -import {Modal, ModalProps} from '@/components/Modal' -import {IconButton} from '@/components/IconButton' interface Code { url: string diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/Row/Row.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/Row/Row.tsx index 950066fc2a7..f22e510955b 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/Row/Row.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/Row/Row.tsx @@ -1,7 +1,6 @@ import * as styles from './Row.module.scss' - -import React from 'react' import {classNames} from '@/utilities/css' +import React from 'react' interface Props extends React.HTMLProps { children: React.ReactNode diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/components/Status/Status.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/components/Status/Status.tsx index cfad70449b0..ffd9ce15905 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/components/Status/Status.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/components/Status/Status.tsx @@ -1,10 +1,9 @@ -import * as styles from './Status.module.scss' import en from './translations/en.json' - +import * as styles from './Status.module.scss' +import {Tooltip} from '@/components/Tooltip' import React from 'react' import {useI18n} from '@shopify/react-i18n' import {Status as StatusProp} from '@shopify/ui-extensions-server-kit' -import {Tooltip} from '@/components/Tooltip' interface Props { status: StatusProp diff --git a/packages/ui-extensions-dev-console/src/sections/Extensions/hooks/useNavigate.tsx b/packages/ui-extensions-dev-console/src/sections/Extensions/hooks/useNavigate.tsx index 05a7e1136df..f2a2d482cd5 100644 --- a/packages/ui-extensions-dev-console/src/sections/Extensions/hooks/useNavigate.tsx +++ b/packages/ui-extensions-dev-console/src/sections/Extensions/hooks/useNavigate.tsx @@ -4,6 +4,5 @@ import {useMemo} from 'react' export function useNavigate() { const extensionServer = useExtensionServerContext() - // eslint-disable-next-line @typescript-eslint/unbound-method return useMemo(() => (url: string) => extensionServer.client.emit('navigate', {url}), [extensionServer.client.emit]) } diff --git a/packages/ui-extensions-dev-console/tests/MockI18nProvider.tsx b/packages/ui-extensions-dev-console/tests/MockI18nProvider.tsx index 84a5ca4028f..8ffff30518e 100644 --- a/packages/ui-extensions-dev-console/tests/MockI18nProvider.tsx +++ b/packages/ui-extensions-dev-console/tests/MockI18nProvider.tsx @@ -1,8 +1,7 @@ import React from 'react' import {I18nContext, I18nManager} from '@shopify/react-i18n' -export function MockI18nProvider({children}: React.PropsWithChildren<{[key: string]: unknown}>) { - // eslint-disable-next-line react/jsx-no-constructed-context-values +export function MockI18nProvider({children}: React.PropsWithChildren>) { const i18nManager = new I18nManager({ locale: 'en', onError(error) { diff --git a/packages/ui-extensions-server-kit/src/ExtensionServerClient/ExtensionServerClient.test.ts b/packages/ui-extensions-server-kit/src/ExtensionServerClient/ExtensionServerClient.test.ts index 1eb1ec10c3d..8ef4ffa1aea 100644 --- a/packages/ui-extensions-server-kit/src/ExtensionServerClient/ExtensionServerClient.test.ts +++ b/packages/ui-extensions-server-kit/src/ExtensionServerClient/ExtensionServerClient.test.ts @@ -1,8 +1,9 @@ import {ExtensionServerClient} from './ExtensionServerClient' import {DeepPartial} from '../types' import {mockApp} from '../testing' -import {beforeEach, expect, test, vi, describe} from 'vitest' + import {Localization} from 'i18n.js' +import {beforeEach, expect, test, vi, describe} from 'vitest' // Mock React's act function because jest-websocket-mock tries to use it vi.mock('react-dom/test-utils', () => ({ @@ -51,7 +52,7 @@ class MockWebSocket implements Partial { onmessage: ((ev: MessageEvent) => any) | null = null onclose: ((ev: CloseEvent) => any) | null = null server: MockWebSocketServer - private eventListeners: {[key: string]: Set} = { + private eventListeners: Record> = { open: new Set(), message: new Set(), close: new Set(), @@ -1032,7 +1033,7 @@ describe('ExtensionServerClient', () => { mockSocketServer.connect(mockSocket) // Persist data - const extensionData = {extensions: [{uuid: '123'}]} + const extensionData = {extensions: [{uuid: '123'}]} as any client.persist('update', extensionData) // Verify the correct message was sent @@ -1092,7 +1093,7 @@ describe('ExtensionServerClient', () => { extensionPoints: [{localization: {}, name: 'いらっしゃいませ!', description: '拡張子の説明'}], }, ], - } + } as any // Persist the data client.persist('update', extensionData) @@ -1125,7 +1126,7 @@ describe('ExtensionServerClient', () => { // Create data with localization fields const extensionData = { extensions: [{uuid: '123', type: 'ui_extension', localization: {}, extensionPoints: [{localization: {}}]}], - } + } as any // Persist the data client.persist('update', extensionData) diff --git a/packages/ui-extensions-server-kit/src/ExtensionServerClient/ExtensionServerClient.ts b/packages/ui-extensions-server-kit/src/ExtensionServerClient/ExtensionServerClient.ts index c914dddf8e5..507bfb5df73 100644 --- a/packages/ui-extensions-server-kit/src/ExtensionServerClient/ExtensionServerClient.ts +++ b/packages/ui-extensions-server-kit/src/ExtensionServerClient/ExtensionServerClient.ts @@ -1,7 +1,6 @@ -/* eslint-disable @typescript-eslint/no-dynamic-delete */ /* eslint-disable no-console */ -import {Surface} from './types.js' import {ExtensionServer} from './server-types.js' +import {Surface} from './types.js' import { FlattenedLocalization, Localization, @@ -21,12 +20,16 @@ export class ExtensionServerClient implements ExtensionServer.Client { protected EVENT_THAT_WILL_MUTATE_THE_SERVER = ['update'] - protected listeners: {[key: string]: Set} = {} - protected connectionListeners: {close: Set; open: Set} = {close: new Set(), open: new Set()} + // eslint-disable-next-line @typescript-eslint/no-explicit-any + protected listeners: Record void>> = {} + protected connectionListeners: {close: Set<(event: Event) => void>; open: Set<(event: Event) => void>} = { + close: new Set(), + open: new Set(), + } protected connected = false - private uiExtensionsByUuid: {[key: string]: ExtensionServer.UIExtension} = {} + private uiExtensionsByUuid: Record = {} constructor(options: DeepPartial = {}) { this.id = (Math.random() + 1).toString(36).substring(7) @@ -47,7 +50,7 @@ export class ExtensionServerClient implements ExtensionServer.Client { const optionsChanged = JSON.stringify(newOptions) !== JSON.stringify(this.options) if (optionsChanged) { - this.options = newOptions + this.options = newOptions as ExtensionServer.Options this.setupConnection(true) } @@ -102,14 +105,17 @@ export class ExtensionServerClient implements ExtensionServer.Client { * } * ``` */ - data.extensions?.forEach((extension: any) => { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ;(data as any).extensions?.forEach((extension: ExtensionPayload) => { TRANSLATED_KEYS.forEach((key) => { if (isUIExtension(extension)) { extension.extensionPoints?.forEach((extensionPoint) => { - delete extensionPoint[key as keyof ExtensionPoint] + // eslint-disable-next-line @typescript-eslint/no-explicit-any + delete (extensionPoint as any)[key] }) } - delete extension[key as keyof ExtensionPayload] + // eslint-disable-next-line @typescript-eslint/no-explicit-any + delete (extension as any)[key] }) }) return this.connection?.send(JSON.stringify({event, data})) @@ -119,7 +125,8 @@ export class ExtensionServerClient implements ExtensionServer.Client { } public emit(...args: ExtensionServer.EmitArgs): void { - const [event, data] = args + const event = args[0] + const data = args.length > 1 ? args[1] : undefined if (this.EVENT_THAT_WILL_MUTATE_THE_SERVER.includes(event as string)) { return console.warn( @@ -156,19 +163,20 @@ export class ExtensionServerClient implements ExtensionServer.Client { this.connection?.addEventListener('message', (message) => { try { const {event, data} = JSON.parse(message.data) as ExtensionServer.ServerEvents + const typedData = data if (event === 'dispatch') { - const {type, payload} = data + const {type, payload} = typedData as {type: string; payload: unknown} this.listeners[type]?.forEach((listener) => listener(payload)) return } - const filteredExtensions = data.extensions - ? filterExtensionsBySurface(data.extensions, this.options.surface) - : data.extensions + const filteredExtensions = typedData.extensions + ? filterExtensionsBySurface(typedData.extensions, this.options.surface) + : typedData.extensions this.listeners[event]?.forEach((listener) => { - listener({...data, extensions: this._getLocalizedExtensions(filteredExtensions)}) + listener({...typedData, extensions: this._getLocalizedExtensions(filteredExtensions)}) }) // eslint-disable-next-line no-catch-all/no-catch-all } catch (err) { @@ -213,9 +221,9 @@ export class ExtensionServerClient implements ExtensionServer.Client { const localization = shouldUpdateTranslations ? getFlattenedLocalization(extension.localization, this.options.locales) - : this.uiExtensionsByUuid[extension.uuid]?.localization ?? extension.localization + : (this.uiExtensionsByUuid[extension.uuid]?.localization ?? extension.localization) - const parsedTranslation: {[key: string]: string} = + const parsedTranslation: Record = localization && isFlattenedTranslations(localization) ? JSON.parse(localization.translations) : localization const localizedExtension = { @@ -260,7 +268,7 @@ export class ExtensionServerClient implements ExtensionServer.Client { }) } - private _getLocalizedValue(translations: {[x: string]: string}, value: string): string { + private _getLocalizedValue(translations: Record, value: string): string { const translationKey = value.replace('t:', '') return translations[translationKey] || value } @@ -295,7 +303,7 @@ function filterExtensionsBySurface(extensions: ExtensionPayload[], surface: Surf } if (Array.isArray(extension.extensionPoints)) { - const extensionPoints: (string | {surface: Surface; [key: string]: any})[] = extension.extensionPoints + const extensionPoints = extension.extensionPoints as (string | {surface: Surface; [key: string]: unknown})[] const extensionPointMatchingSurface = extensionPoints.filter((extensionPoint) => { if (typeof extensionPoint === 'string') { return false diff --git a/packages/ui-extensions-server-kit/src/ExtensionServerClient/server-types.ts b/packages/ui-extensions-server-kit/src/ExtensionServerClient/server-types.ts index 98e658863e4..51375c4a962 100644 --- a/packages/ui-extensions-server-kit/src/ExtensionServerClient/server-types.ts +++ b/packages/ui-extensions-server-kit/src/ExtensionServerClient/server-types.ts @@ -1,7 +1,8 @@ import {Surface} from './types.js' -import {ExtensionPayload, ExtensionPoint} from '../types' -import {FlattenedLocalization, Localization} from '../i18n' +import {ExtensionPayload, ExtensionPoint, App} from '../types' +import {FlattenedLocalization, LocalesOptions, Localization} from '../i18n' +// Re-export and augment the global ExtensionServer namespace export namespace ExtensionServer { export interface UIExtension extends ExtensionPayload { extensionPoints: ExtensionPoint[] @@ -29,24 +30,33 @@ export namespace ExtensionServer { protocols?: string | string[] } surface?: Surface - locales?: any + locales?: LocalesOptions } export interface ServerEvents { event: string + // eslint-disable-next-line @typescript-eslint/no-explicit-any data: any } - export interface InboundEvents { - [key: string]: any + export interface InboundEvents extends DispatchEvents { + dispatch: {type: keyof DispatchEvents; payload: DispatchEvents[keyof DispatchEvents]} + connected: {extensions: ExtensionPayload[]; app?: App; store: string} + update: {extensions?: ExtensionPayload[]; app?: App} } export interface OutboundPersistEvents { - [key: string]: any + update: { + extensions?: ExtensionPayload[] + app?: App + } } export interface DispatchEvents { - [key: string]: any + refresh: {uuid: string}[] + focus: {uuid: string}[] + unfocus: void + navigate: {url: string} } export type EmitArgs = undefined extends DispatchEvents[TEvent] diff --git a/packages/ui-extensions-server-kit/src/ExtensionServerClient/types.ts b/packages/ui-extensions-server-kit/src/ExtensionServerClient/types.ts index 3fcdad48959..3eae4b15b79 100644 --- a/packages/ui-extensions-server-kit/src/ExtensionServerClient/types.ts +++ b/packages/ui-extensions-server-kit/src/ExtensionServerClient/types.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-invalid-void-type */ -/* eslint-disable @typescript-eslint/no-empty-interface */ import type {LocalesOptions} from '../i18n' declare global { diff --git a/packages/ui-extensions-server-kit/src/context/ExtensionServerProvider.test.tsx b/packages/ui-extensions-server-kit/src/context/ExtensionServerProvider.test.tsx index 290973a207f..04af2420f6b 100644 --- a/packages/ui-extensions-server-kit/src/context/ExtensionServerProvider.test.tsx +++ b/packages/ui-extensions-server-kit/src/context/ExtensionServerProvider.test.tsx @@ -1,9 +1,12 @@ import {ExtensionServerProvider} from './ExtensionServerProvider' -import {mockApp, mockExtension} from '../testing' import {useExtensionServerContext} from '../hooks' import {createConnectedAction} from '../state' -import {renderHook, withProviders} from '@shopify/ui-extensions-test-utils' +import {mockApp, mockExtension} from '../testing' import {beforeEach, afterEach, expect} from 'vitest' +import {renderHook, withProviders} from '@shopify/ui-extensions-test-utils' + +// Cast provider to any to avoid type conflicts between required props and ProviderComponent +const TestProvider = ExtensionServerProvider as Parameters[0] // Create a custom mock WebSocket implementation to avoid using jest-websocket-mock class MockWebSocketServer { @@ -45,7 +48,7 @@ class MockWebSocket implements Partial { onmessage: ((ev: MessageEvent) => any) | null = null onclose: ((ev: CloseEvent) => any) | null = null server: MockWebSocketServer - private eventListeners: {[key: string]: Set} = { + private eventListeners: Record> = { open: new Set(), message: new Set(), close: new Set(), @@ -142,7 +145,7 @@ describe('ExtensionServerProvider tests', () => { test('creates a new ExtensionServerClient instance', async () => { const options = {connection: {url: 'ws://example-host.com:8000/extensions/'}} - const wrapper = renderHook(useExtensionServerContext, withProviders(ExtensionServerProvider), {options}) + const wrapper = renderHook(useExtensionServerContext, withProviders(TestProvider), {options}) expect(wrapper.result.client).toBeDefined() }) @@ -150,7 +153,7 @@ describe('ExtensionServerProvider tests', () => { test('does not start a new connection if an empty url is passed', async () => { const options = {connection: {}} - const wrapper = renderHook(useExtensionServerContext, withProviders(ExtensionServerProvider), {options}) + const wrapper = renderHook(useExtensionServerContext, withProviders(TestProvider), {options}) expect(wrapper.result.client.connection).toBeUndefined() }) @@ -160,7 +163,7 @@ describe('ExtensionServerProvider tests', () => { test('starts a new connection by calling connect', async () => { const options = {connection: {url: 'ws://example-host.com:8000/extensions/'}} - const wrapper = renderHook(useExtensionServerContext, withProviders(ExtensionServerProvider), { + const wrapper = renderHook(useExtensionServerContext, withProviders(TestProvider), { options: { connection: {url: ''}, }, @@ -181,7 +184,7 @@ describe('ExtensionServerProvider tests', () => { const app = mockApp() const extension = mockExtension() const payload = {app, extensions: [extension], store: 'test-store.com'} - const wrapper = renderHook(useExtensionServerContext, withProviders(ExtensionServerProvider), {options}) + const wrapper = renderHook(useExtensionServerContext, withProviders(TestProvider), {options}) wrapper.act(({dispatch}) => { dispatch({type: 'connected', payload}) @@ -201,7 +204,7 @@ describe('ExtensionServerProvider tests', () => { const extension = mockExtension() const data = {app, store: 'test-store.com', extensions: [extension]} const options = {connection: {url: 'ws://example-host.com:8000/extensions/'}} - const wrapper = renderHook(useExtensionServerContext, withProviders(ExtensionServerProvider), {options}) + const wrapper = renderHook(useExtensionServerContext, withProviders(TestProvider), {options}) // Since we can't be sure the socket connection works properly in the test environment // Initialize data through the dispatch action instead @@ -223,7 +226,7 @@ describe('ExtensionServerProvider tests', () => { const update = {...extension, version: 'v2'} const data = {app, store: 'test-store.com', extensions: [extension]} const options = {connection: {url: 'ws://example-host.com:8000/extensions/'}} - const wrapper = renderHook(useExtensionServerContext, withProviders(ExtensionServerProvider), {options}) + const wrapper = renderHook(useExtensionServerContext, withProviders(TestProvider), {options}) // Initialize state with connected data wrapper.act(({dispatch}) => { @@ -248,7 +251,7 @@ describe('ExtensionServerProvider tests', () => { const extension = mockExtension() const data = {app, store: 'test-store.com', extensions: [extension]} const options = {connection: {url: 'ws://example-host.com:8000/extensions/'}} - const wrapper = renderHook(useExtensionServerContext, withProviders(ExtensionServerProvider), {options}) + const wrapper = renderHook(useExtensionServerContext, withProviders(TestProvider), {options}) // Initialize state with connected data wrapper.act(({dispatch}) => { @@ -272,7 +275,7 @@ describe('ExtensionServerProvider tests', () => { } const data = {app, store: 'test-store.com', extensions: [extension]} const options = {connection: {url: 'ws://example-host.com:8000/extensions/'}} - const wrapper = renderHook(useExtensionServerContext, withProviders(ExtensionServerProvider), {options}) + const wrapper = renderHook(useExtensionServerContext, withProviders(TestProvider), {options}) // Initialize state with connected data wrapper.act(({dispatch}) => { @@ -309,7 +312,7 @@ describe('ExtensionServerProvider tests', () => { const data = {app, store: 'test-store.com', extensions: [extension]} const options = {connection: {url: 'ws://example-host.com:8000/extensions/'}} - const wrapper = renderHook(useExtensionServerContext, withProviders(ExtensionServerProvider), {options}) + const wrapper = renderHook(useExtensionServerContext, withProviders(TestProvider), {options}) // Initialize state with connected data wrapper.act(({dispatch}) => { diff --git a/packages/ui-extensions-server-kit/src/context/ExtensionServerProvider.tsx b/packages/ui-extensions-server-kit/src/context/ExtensionServerProvider.tsx index 3b4da57d6cb..ee918de6691 100644 --- a/packages/ui-extensions-server-kit/src/context/ExtensionServerProvider.tsx +++ b/packages/ui-extensions-server-kit/src/context/ExtensionServerProvider.tsx @@ -11,6 +11,7 @@ import {ExtensionServerClient} from '../ExtensionServerClient' import {ExtensionServer} from '../ExtensionServerClient/server-types.js' import {useIsomorphicLayoutEffect} from '../hooks/useIsomorphicLayoutEffect' import {useExtensionServerState} from '../hooks/useExtensionServerState' + import React, {useCallback, useMemo, useState} from 'react' import type {ExtensionServerProviderProps} from './types' diff --git a/packages/ui-extensions-server-kit/src/i18n.ts b/packages/ui-extensions-server-kit/src/i18n.ts index 28e15b503ba..e1a43c5c9c6 100644 --- a/packages/ui-extensions-server-kit/src/i18n.ts +++ b/packages/ui-extensions-server-kit/src/i18n.ts @@ -6,7 +6,7 @@ type Translation = string | {[key: string]: Translation} export interface Localization { defaultLocale: string - translations: {[key: string]: {[key: string]: Translation}} + translations: Record> lastUpdated: number } @@ -63,9 +63,7 @@ interface TranslationDictionary { * } * ``` */ -interface ExtensionTranslationMap { - [key: string]: string -} +type ExtensionTranslationMap = Record export const TRANSLATED_KEYS = ['localization', 'name', 'description'] /** @@ -105,7 +103,6 @@ function traverseDictionary( } if (typeof value === 'string') { - // eslint-disable-next-line node/callback-return callback(translationKey, value) } else { traverseDictionary(value, callback, translationKey) diff --git a/packages/ui-extensions-server-kit/src/state/reducers/extensionServerReducer.test.ts b/packages/ui-extensions-server-kit/src/state/reducers/extensionServerReducer.test.ts index 8b3da54deb5..8046b5e8e3c 100644 --- a/packages/ui-extensions-server-kit/src/state/reducers/extensionServerReducer.test.ts +++ b/packages/ui-extensions-server-kit/src/state/reducers/extensionServerReducer.test.ts @@ -103,7 +103,7 @@ describe('extensionServerReducer()', () => { const action = createRefreshAction([{uuid: extension.uuid}]) const state1 = extensionServerReducer(previousState, action) - // eslint-disable-next-line node/no-unsupported-features/node-builtins + const url1 = new URL(state1.extensions[0].assets.main.url) const timestamp1 = url1.searchParams.get('lastUpdated') ?? '' @@ -113,7 +113,7 @@ describe('extensionServerReducer()', () => { await new Promise((resolve) => setTimeout(resolve, 1)) const state2 = extensionServerReducer(state1, action) - // eslint-disable-next-line node/no-unsupported-features/node-builtins + const url2 = new URL(state2.extensions[0].assets.main.url) const timestamp2 = url2.searchParams.get('lastUpdated') ?? '' diff --git a/packages/ui-extensions-server-kit/src/types.ts b/packages/ui-extensions-server-kit/src/types.ts index ed27db533fc..1aec8c71183 100644 --- a/packages/ui-extensions-server-kit/src/types.ts +++ b/packages/ui-extensions-server-kit/src/types.ts @@ -1,5 +1,3 @@ -/* eslint-disable @typescript-eslint/no-invalid-void-type */ -/* eslint-disable @shopify/strict-component-boundaries */ import {FlattenedLocalization, Localization} from './i18n' import './ExtensionServerClient/types' import type {Surface} from './ExtensionServerClient/types' @@ -94,7 +92,7 @@ export interface ExtensionPoint { localization?: FlattenedLocalization | Localization | null name: string description?: string - assets?: {[name: string]: Asset} + assets?: Record } type ExtensionPoints = string[] | ExtensionPoint[] | null @@ -119,7 +117,7 @@ interface Capabilities { export interface ExtensionPayload { type: string externalType: string - assets: {[name: string]: Asset} + assets: Record development: { hidden: boolean status: Status @@ -154,7 +152,7 @@ export interface ExtensionPayload { name?: string description?: string required?: boolean - validations?: any[] + validations?: unknown[] }[] } } diff --git a/packages/ui-extensions-server-kit/src/utilities/assetToString.ts b/packages/ui-extensions-server-kit/src/utilities/assetToString.ts index d1db8b78ae4..97a84dae5e8 100644 --- a/packages/ui-extensions-server-kit/src/utilities/assetToString.ts +++ b/packages/ui-extensions-server-kit/src/utilities/assetToString.ts @@ -1,7 +1,6 @@ import type {Asset} from '../types' export function assetToString(asset: Asset) { - // eslint-disable-next-line node/no-unsupported-features/node-builtins const url = new URL(asset.url) url.searchParams.set('lastUpdated', String(asset.lastUpdated)) return url.toString() diff --git a/packages/ui-extensions-server-kit/src/utilities/isUIExtension.ts b/packages/ui-extensions-server-kit/src/utilities/isUIExtension.ts index e10f60acc40..318618cf770 100644 --- a/packages/ui-extensions-server-kit/src/utilities/isUIExtension.ts +++ b/packages/ui-extensions-server-kit/src/utilities/isUIExtension.ts @@ -1,7 +1,8 @@ -export function isUIExtension(extension: any): extension is ExtensionServer.UIExtension { +export function isUIExtension(extension: unknown): extension is ExtensionServer.UIExtension { + const ext = extension as ExtensionServer.UIExtension return ( - extension.type === 'ui_extension' && - Array.isArray(extension.extensionPoints) && - extension.extensionPoints.every((extensionPoint: any) => typeof extensionPoint === 'object') + ext.type === 'ui_extension' && + Array.isArray(ext.extensionPoints) && + ext.extensionPoints.every((extensionPoint: unknown) => typeof extensionPoint === 'object') ) } diff --git a/packages/ui-extensions-server-kit/src/utilities/isValidSurface.ts b/packages/ui-extensions-server-kit/src/utilities/isValidSurface.ts index a6918c62a96..34e2c955f15 100644 --- a/packages/ui-extensions-server-kit/src/utilities/isValidSurface.ts +++ b/packages/ui-extensions-server-kit/src/utilities/isValidSurface.ts @@ -1,7 +1,6 @@ -/* eslint-disable @shopify/strict-component-boundaries */ import {AVAILABLE_SURFACES} from '../ExtensionServerClient/types' import type {Surface} from '../ExtensionServerClient/types' -export function isValidSurface(surface: any): surface is Surface { - return surface && AVAILABLE_SURFACES.includes(surface) +export function isValidSurface(surface: unknown): surface is Surface { + return Boolean(surface) && AVAILABLE_SURFACES.includes(surface as Surface) } diff --git a/packages/ui-extensions-server-kit/src/utilities/replaceUpdated.ts b/packages/ui-extensions-server-kit/src/utilities/replaceUpdated.ts index 479c91daa83..e3e98028b9e 100644 --- a/packages/ui-extensions-server-kit/src/utilities/replaceUpdated.ts +++ b/packages/ui-extensions-server-kit/src/utilities/replaceUpdated.ts @@ -1,10 +1,8 @@ export function replaceUpdated(arr: T[], updates: T[], cb: (v: T) => unknown): T[] { const updatesMap = new Map(updates.map((updated) => [cb(updated), updated])) const updated = arr.map((item) => { - // eslint-disable-next-line node/callback-return const key = cb(item) if (updatesMap.has(key)) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const updated = updatesMap.get(key)! updatesMap.delete(key) return updated diff --git a/packages/ui-extensions-server-kit/src/utilities/set.ts b/packages/ui-extensions-server-kit/src/utilities/set.ts index 68a68bbd3d1..4885a10d23f 100644 --- a/packages/ui-extensions-server-kit/src/utilities/set.ts +++ b/packages/ui-extensions-server-kit/src/utilities/set.ts @@ -1,9 +1,13 @@ /** * Deep sets an object in a type-safe way */ -export function set(obj: TObject, pathFn: (o: TObject) => TValue, value: TValue) { +export function set( + obj: TObject, + pathFn: (o: TObject) => TValue, + value: TValue, +): TObject { const path: string[] = [] - const proxy: any = new Proxy( + const proxy: unknown = new Proxy( {}, { get: (_, prop: string) => { @@ -12,11 +16,12 @@ export function set(obj: TObject, pathFn: (o: TObject) => TValu }, }, ) - pathFn(proxy) + pathFn(proxy as TObject) - const newObj: TObject = {...obj} + const newObj = {...obj} + // eslint-disable-next-line @typescript-eslint/no-explicit-any let current: any = newObj - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const lastKey = path.pop()! for (const key of path) { diff --git a/packages/ui-extensions-test-utils/src/renderHook.tsx b/packages/ui-extensions-test-utils/src/renderHook.tsx index 3ce6b96169a..51aa319da3f 100644 --- a/packages/ui-extensions-test-utils/src/renderHook.tsx +++ b/packages/ui-extensions-test-utils/src/renderHook.tsx @@ -28,7 +28,7 @@ export function renderHook( Providers: React.ComponentType> = ({children}) => <>{children}, options: Omit = {} as TP, ) { - const hookResult: HookWrapper = {} as any + const hookResult: HookWrapper = {} as HookWrapper const wrapper = mount( (hookResult.result = hook())} /> diff --git a/packages/ui-extensions-test-utils/src/withProviders.ts b/packages/ui-extensions-test-utils/src/withProviders.ts index f7b58ce4be7..483b79c0a70 100644 --- a/packages/ui-extensions-test-utils/src/withProviders.ts +++ b/packages/ui-extensions-test-utils/src/withProviders.ts @@ -1,19 +1,16 @@ -/* eslint-disable @typescript-eslint/no-empty-interface */ import React from 'react' -export type ProviderComponent = React.ComponentType> +export type ProviderComponent = React.ComponentType> -export type Tail = T extends [head: any, ...tail: infer TRest] ? TRest : never - -export type PropUnion< - TProviders extends any[], - TProps extends {[k: string]: any} = Empty, -> = TProviders[0] extends React.ComponentType - ? React.ComponentPropsWithoutRef & PropUnion> - : TProps +export type Tail = T extends [head: unknown, ...tail: infer TRest] ? TRest : never export interface Empty {} +export type PropUnion = Record> = + TProviders[0] extends React.ComponentType + ? React.ComponentPropsWithoutRef & PropUnion> + : TProps + export function withProviders(...providers: T): ProviderComponent> { return function Providers({children, ...props}) { return providers.reduceRight(