-
Notifications
You must be signed in to change notification settings - Fork 155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[stable] Fix bug with contracts and missing fields #5483
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Coverage report
Test suite run success2084 tests passing in 924 suites. Report generated by 🧪jest coverage report action from f80b326 |
Differences in type declarationsWe detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:
New type declarationsWe found no new type declarations in this PR Existing type declarationspackages/cli-kit/dist/private/node/api.d.ts@@ -1,41 +1,18 @@
import { Headers } from 'form-data';
export type API = 'admin' | 'storefront-renderer' | 'partners' | 'business-platform' | 'app-management';
export declare const allAPIs: API[];
-export type NetworkRetryBehaviour = {
- useNetworkLevelRetry: true;
- maxRetryTimeMs: number;
-} | {
- useNetworkLevelRetry: false;
-};
-type RequestOptions<T> = {
+interface RequestOptions<T> {
request: () => Promise<T>;
url: string;
-} & NetworkRetryBehaviour;
+}
export declare function simpleRequestWithDebugLog<T extends {
headers: Headers;
status: number;
-}>(requestOptions: RequestOptions<T>, errorHandler?: (error: unknown, requestId: string | undefined) => unknown): Promise<T>;
-/**
- * Makes a HTTP request to some API, retrying if response headers indicate a retryable error.
- *
- * If a request fails with a 429, the retry-after header determines a delay before an automatic retry is performed.
- *
- * If unauthorizedHandler is provided, then it will be called in the case of a 401 and a retry performed. This allows
- * for a token refresh for instance.
- *
- * If there's a network error, e.g. DNS fails to resolve, then API calls are automatically retried.
- *
- * @param request - A function that returns a promise of the response
- * @param url - The URL to request
- * @param errorHandler - A function that handles errors
- * @param unauthorizedHandler - A function that handles unauthorized errors
- * @param retryOptions - Options for the retry
- * @returns The response from the request
- */
+}>({ request, url }: RequestOptions<T>, errorHandler?: (error: unknown, requestId: string | undefined) => unknown): Promise<T>;
export declare function retryAwareRequest<T extends {
headers: Headers;
status: number;
-}>(requestOptions: RequestOptions<T>, errorHandler?: (error: unknown, requestId: string | undefined) => unknown, unauthorizedHandler?: () => Promise<void>, retryOptions?: {
+}>({ request, url }: RequestOptions<T>, errorHandler?: (error: unknown, requestId: string | undefined) => unknown, unauthorizedHandler?: () => Promise<void>, retryOptions?: {
limitRetriesTo?: number;
defaultDelayMs?: number;
scheduleDelay: (fn: () => void, delay: number) => void;
packages/cli-kit/dist/private/node/constants.d.ts@@ -32,8 +32,6 @@ export declare const environmentVariables: {
themeKitAccessDomain: string;
json: string;
neverUsePartnersApi: string;
- skipNetworkLevelRetry: string;
- maxRequestTimeForNetworkCalls: string;
};
export declare const defaultThemeKitAccessDomain = "theme-kit-access.shopifyapps.com";
export declare const systemEnvironmentVariables: {
packages/cli-kit/dist/public/node/environment.d.ts@@ -55,24 +55,4 @@ export declare function jsonOutputEnabled(environment?: NodeJS.ProcessEnv): bool
*
* @returns True if the SHOPIFY_CLI_NEVER_USE_PARTNERS_API environment variable is set.
*/
-export declare function blockPartnersAccess(): boolean;
-/**
- * If true, the CLI should not use the network level retry.
- *
- * If there is an error when calling a network API that looks like a DNS or connectivity issue, the CLI will by default
- * automatically retry the request.
- *
- * @param environment - Process environment variables.
- * @returns True if the SHOPIFY_CLI_SKIP_NETWORK_LEVEL_RETRY environment variable is set.
- */
-export declare function skipNetworkLevelRetry(environment?: NodeJS.ProcessEnv): boolean;
-/**
- * Returns the default maximum request time for network calls in milliseconds.
- *
- * After this long, API requests may be cancelled by an AbortSignal. The limit can be overridden by setting the
- * SHOPIFY_CLI_MAX_REQUEST_TIME_FOR_NETWORK_CALLS environment variable.
- *
- * @param environment - Process environment variables.
- * @returns The maximum request time in milliseconds.
- */
-export declare function maxRequestTimeForNetworkCallsMs(environment?: NodeJS.ProcessEnv): number;
\ No newline at end of file
+export declare function blockPartnersAccess(): boolean;
\ No newline at end of file
packages/cli-kit/dist/public/node/http.d.ts@@ -1,4 +1,3 @@
-import { NetworkRetryBehaviour } from '../../private/node/api.js';
import FormData from 'form-data';
import { RequestInfo, RequestInit, Response } from 'node-fetch';
export { FetchError, Request, Response } from 'node-fetch';
@@ -8,43 +7,6 @@ export { FetchError, Request, Response } from 'node-fetch';
* @returns A FormData object.
*/
export declare function formData(): FormData;
-type AbortSignal = RequestInit['signal'];
-type PresetFetchBehaviour = 'default' | 'non-blocking' | 'slow-request';
-type AutomaticCancellationBehaviour = {
- useAbortSignal: true;
- timeoutMs: number;
-} | {
- useAbortSignal: false;
-} | {
- useAbortSignal: AbortSignal | (() => AbortSignal);
-};
-type RequestBehaviour = NetworkRetryBehaviour & AutomaticCancellationBehaviour;
-type RequestModeInput = PresetFetchBehaviour | RequestBehaviour;
-/**
- * Specify the behaviour of a network request.
- *
- * - default: Requests are automatically retried, and are subject to automatic cancellation if they're taking too long.
- * This is generally desirable.
- * - non-blocking: Requests are not retried if they fail with a network error, and are automatically cancelled if
- * they're taking too long. This is good for throwaway requests, like polling or tracking.
- * - slow-request: Requests are not retried if they fail with a network error, and are not automatically cancelled.
- * This is good for slow requests that should be give the chance to complete, and are unlikely to be safe to retry.
- *
- * Some request behaviours may be de-activated by the environment, and this function takes care of that concern. You
- * can also provide a customised request behaviour.
- *
- * @param preset - The preset to use.
- * @param env - Process environment variables.
- * @returns A request behaviour object.
- */
-export declare function requestMode(preset?: RequestModeInput, env?: NodeJS.ProcessEnv): RequestBehaviour;
-/**
- * Create an AbortSignal for automatic request cancellation, from a request behaviour.
- *
- * @param behaviour - The request behaviour.
- * @returns An AbortSignal.
- */
-export declare function abortSignalFromRequestBehaviour(behaviour: RequestBehaviour): AbortSignal;
/**
* An interface that abstracts way node-fetch. When Node has built-in
* support for "fetch" in the standard library, we can drop the node-fetch
@@ -53,28 +15,21 @@ export declare function abortSignalFromRequestBehaviour(behaviour: RequestBehavi
* they are consistent with the Web API so if we drop node-fetch in the future
* it won't require changes from the callers.
*
- * The CLI's fetch function supports special behaviours, like automatic retries. These are disabled by default through
- * this function.
- *
* @param url - This defines the resource that you wish to fetch.
* @param init - An object containing any custom settings that you want to apply to the request.
- * @param preferredBehaviour - A request behaviour object that overrides the default behaviour.
* @returns A promise that resolves with the response.
*/
-export declare function fetch(url: RequestInfo, init?: RequestInit, preferredBehaviour?: RequestModeInput): Promise<Response>;
+export declare function fetch(url: RequestInfo, init?: RequestInit): Promise<Response>;
/**
* A fetch function to use with Shopify services. The function ensures the right
* TLS configuragion is used based on the environment in which the service is running
- * (e.g. Spin). NB: headers/auth are the responsibility of the caller.
- *
- * By default, the CLI's fetch function's special behaviours, like automatic retries, are enabled.
+ * (e.g. Spin).
*
* @param url - This defines the resource that you wish to fetch.
* @param init - An object containing any custom settings that you want to apply to the request.
- * @param preferredBehaviour - A request behaviour object that overrides the default behaviour.
* @returns A promise that resolves with the response.
*/
-export declare function shopifyFetch(url: RequestInfo, init?: RequestInit, preferredBehaviour?: RequestModeInput): Promise<Response>;
+export declare function shopifyFetch(url: RequestInfo, init?: RequestInit): Promise<Response>;
/**
* Download a file from a URL to a local path.
*
packages/cli-kit/dist/private/node/session/schema.d.ts@@ -9,15 +9,15 @@ declare const IdentityTokenSchema: zod.ZodObject<{
scopes: zod.ZodArray<zod.ZodString, "many">;
userId: zod.ZodString;
}, "strip", zod.ZodTypeAny, {
+ scopes: string[];
accessToken: string;
refreshToken: string;
- scopes: string[];
expiresAt: Date;
userId: string;
}, {
+ scopes: string[];
accessToken: string;
refreshToken: string;
- scopes: string[];
userId: string;
expiresAt?: unknown;
}>;
@@ -29,12 +29,12 @@ declare const ApplicationTokenSchema: zod.ZodObject<{
expiresAt: zod.ZodEffects<zod.ZodDate, Date, unknown>;
scopes: zod.ZodArray<zod.ZodString, "many">;
}, "strip", zod.ZodTypeAny, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt: Date;
}, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt?: unknown;
}>;
/**
@@ -58,15 +58,15 @@ export declare const SessionSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{
scopes: zod.ZodArray<zod.ZodString, "many">;
userId: zod.ZodString;
}, "strip", zod.ZodTypeAny, {
+ scopes: string[];
accessToken: string;
refreshToken: string;
- scopes: string[];
expiresAt: Date;
userId: string;
}, {
+ scopes: string[];
accessToken: string;
refreshToken: string;
- scopes: string[];
userId: string;
expiresAt?: unknown;
}>;
@@ -79,65 +79,65 @@ export declare const SessionSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{
expiresAt: zod.ZodEffects<zod.ZodDate, Date, unknown>;
scopes: zod.ZodArray<zod.ZodString, "many">;
}, "strip", zod.ZodTypeAny, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt: Date;
}, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt?: unknown;
}>, zod.objectOutputType<{}, zod.ZodObject<{
accessToken: zod.ZodString;
expiresAt: zod.ZodEffects<zod.ZodDate, Date, unknown>;
scopes: zod.ZodArray<zod.ZodString, "many">;
}, "strip", zod.ZodTypeAny, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt: Date;
}, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt?: unknown;
}>, "strip">, zod.objectInputType<{}, zod.ZodObject<{
accessToken: zod.ZodString;
expiresAt: zod.ZodEffects<zod.ZodDate, Date, unknown>;
scopes: zod.ZodArray<zod.ZodString, "many">;
}, "strip", zod.ZodTypeAny, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt: Date;
}, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt?: unknown;
}>, "strip">>;
}, "strip", zod.ZodTypeAny, {
identity: {
+ scopes: string[];
accessToken: string;
refreshToken: string;
- scopes: string[];
expiresAt: Date;
userId: string;
};
applications: {} & {
[k: string]: {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt: Date;
};
};
}, {
identity: {
+ scopes: string[];
accessToken: string;
refreshToken: string;
- scopes: string[];
userId: string;
expiresAt?: unknown;
};
applications: {} & {
[k: string]: {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt?: unknown;
};
};
@@ -154,15 +154,15 @@ export declare const SessionSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{
scopes: zod.ZodArray<zod.ZodString, "many">;
userId: zod.ZodString;
}, "strip", zod.ZodTypeAny, {
+ scopes: string[];
accessToken: string;
refreshToken: string;
- scopes: string[];
expiresAt: Date;
userId: string;
}, {
+ scopes: string[];
accessToken: string;
refreshToken: string;
- scopes: string[];
userId: string;
expiresAt?: unknown;
}>;
@@ -175,65 +175,65 @@ export declare const SessionSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{
expiresAt: zod.ZodEffects<zod.ZodDate, Date, unknown>;
scopes: zod.ZodArray<zod.ZodString, "many">;
}, "strip", zod.ZodTypeAny, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt: Date;
}, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt?: unknown;
}>, zod.objectOutputType<{}, zod.ZodObject<{
accessToken: zod.ZodString;
expiresAt: zod.ZodEffects<zod.ZodDate, Date, unknown>;
scopes: zod.ZodArray<zod.ZodString, "many">;
}, "strip", zod.ZodTypeAny, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt: Date;
}, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt?: unknown;
}>, "strip">, zod.objectInputType<{}, zod.ZodObject<{
accessToken: zod.ZodString;
expiresAt: zod.ZodEffects<zod.ZodDate, Date, unknown>;
scopes: zod.ZodArray<zod.ZodString, "many">;
}, "strip", zod.ZodTypeAny, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt: Date;
}, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt?: unknown;
}>, "strip">>;
}, "strip", zod.ZodTypeAny, {
identity: {
+ scopes: string[];
accessToken: string;
refreshToken: string;
- scopes: string[];
expiresAt: Date;
userId: string;
};
applications: {} & {
[k: string]: {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt: Date;
};
};
}, {
identity: {
+ scopes: string[];
accessToken: string;
refreshToken: string;
- scopes: string[];
userId: string;
expiresAt?: unknown;
};
applications: {} & {
[k: string]: {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt?: unknown;
};
};
@@ -250,15 +250,15 @@ export declare const SessionSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{
scopes: zod.ZodArray<zod.ZodString, "many">;
userId: zod.ZodString;
}, "strip", zod.ZodTypeAny, {
+ scopes: string[];
accessToken: string;
refreshToken: string;
- scopes: string[];
expiresAt: Date;
userId: string;
}, {
+ scopes: string[];
accessToken: string;
refreshToken: string;
- scopes: string[];
userId: string;
expiresAt?: unknown;
}>;
@@ -271,65 +271,65 @@ export declare const SessionSchema: zod.ZodObject<{}, "strip", zod.ZodObject<{
expiresAt: zod.ZodEffects<zod.ZodDate, Date, unknown>;
scopes: zod.ZodArray<zod.ZodString, "many">;
}, "strip", zod.ZodTypeAny, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt: Date;
}, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt?: unknown;
}>, zod.objectOutputType<{}, zod.ZodObject<{
accessToken: zod.ZodString;
expiresAt: zod.ZodEffects<zod.ZodDate, Date, unknown>;
scopes: zod.ZodArray<zod.ZodString, "many">;
}, "strip", zod.ZodTypeAny, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt: Date;
}, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt?: unknown;
}>, "strip">, zod.objectInputType<{}, zod.ZodObject<{
accessToken: zod.ZodString;
expiresAt: zod.ZodEffects<zod.ZodDate, Date, unknown>;
scopes: zod.ZodArray<zod.ZodString, "many">;
}, "strip", zod.ZodTypeAny, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt: Date;
}, {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt?: unknown;
}>, "strip">>;
}, "strip", zod.ZodTypeAny, {
identity: {
+ scopes: string[];
accessToken: string;
refreshToken: string;
- scopes: string[];
expiresAt: Date;
userId: string;
};
applications: {} & {
[k: string]: {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt: Date;
};
};
}, {
identity: {
+ scopes: string[];
accessToken: string;
refreshToken: string;
- scopes: string[];
userId: string;
expiresAt?: unknown;
};
applications: {} & {
[k: string]: {
- accessToken: string;
scopes: string[];
+ accessToken: string;
expiresAt?: unknown;
};
};
|
shauns
approved these changes
Mar 4, 2025
Thank you 💚 |
3 tasks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
WHY are these changes introduced?
The current implementation strips first-class fields before JSON schema validation, which prevents these fields from being used later in the configuration.
This change ensures that common base properties are still included in the extension config (they'll be stripped before deployment)
WHAT is this pull request doing?
JsonSchemaBaseProperties
to define common base properties for all JSON Schema contractstype
,handle
,uid
,path
, andextensions
are preserved in the configurationHow to test your changes?
handle
in your toml that is completely different from thename
attribute. Example toml:app info
you'll see an extension identified asmy-extension
. Because the handle wasn't loaded properly.app info
you'll see the same extension identified assupport-link
, because now the handle was loaded correctly.Measuring impact
Checklist