Skip to content

Commit 04883cc

Browse files
Refresh JSON schema documentation after rebase
1 parent a8e2534 commit 04883cc

6 files changed

Lines changed: 77 additions & 40 deletions

File tree

‎packages/cli/README.md‎

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15583,12 +15583,10 @@ DESCRIPTION
1558315583
"type": "string"
1558415584
},
1558515585
"line": {
15586-
"type": "integer",
15587-
"minimum": 0
15586+
"type": "number"
1558815587
},
1558915588
"col": {
15590-
"type": "integer",
15591-
"minimum": 0
15589+
"type": "number"
1559215590
}
1559315591
},
1559415592
"required": [
@@ -15610,8 +15608,7 @@ DESCRIPTION
1561015608
"type": "number"
1561115609
},
1561215610
"frame": {
15613-
"type": "integer",
15614-
"minimum": 0
15611+
"type": "number"
1561515612
}
1561615613
},
1561715614
"required": [
@@ -15704,8 +15701,7 @@ DESCRIPTION
1570415701
"items": {
1570515702
"type": "array",
1570615703
"items": {
15707-
"type": "integer",
15708-
"minimum": 0
15704+
"type": "number"
1570915705
}
1571015706
}
1571115707
},
@@ -15767,8 +15763,7 @@ DESCRIPTION
1576715763
"type": "string"
1576815764
},
1576915765
"activeProfileIndex": {
15770-
"type": "integer",
15771-
"minimum": 0
15766+
"type": "number"
1577215767
}
1577315768
},
1577415769
"required": [
@@ -15819,6 +15814,11 @@ DESCRIPTION
1581915814
"message": {
1582015815
"type": "string"
1582115816
},
15817+
"code": {
15818+
"type": "string",
15819+
"minLength": 1,
15820+
"description": "A stable error code, included only when known."
15821+
},
1582215822
"tryMessage": {
1582315823
"type": "string"
1582415824
},
@@ -15859,7 +15859,9 @@ DESCRIPTION
1585915859
"additionalProperties": false
1586015860
}
1586115861
},
15862-
"details": {}
15862+
"details": {
15863+
"description": "Selected domain details, preserving native API payloads such as GraphQL errors, extensions, and data."
15864+
}
1586315865
},
1586415866
"required": [
1586515867
"type",
@@ -15877,6 +15879,9 @@ DESCRIPTION
1587715879
"message": {
1587815880
"$ref": "#/definitions/ThemeEnvironment/anyOf/1/properties/error/anyOf/0/properties/message"
1587915881
},
15882+
"code": {
15883+
"$ref": "#/definitions/ThemeEnvironment/anyOf/1/properties/error/anyOf/0/properties/code"
15884+
},
1588015885
"tryMessage": {
1588115886
"$ref": "#/definitions/ThemeEnvironment/anyOf/1/properties/error/anyOf/0/properties/tryMessage"
1588215887
},
@@ -15909,6 +15914,9 @@ DESCRIPTION
1590915914
"message": {
1591015915
"$ref": "#/definitions/ThemeEnvironment/anyOf/1/properties/error/anyOf/0/properties/message"
1591115916
},
15917+
"code": {
15918+
"$ref": "#/definitions/ThemeEnvironment/anyOf/1/properties/error/anyOf/0/properties/code"
15919+
},
1591215920
"tryMessage": {
1591315921
"$ref": "#/definitions/ThemeEnvironment/anyOf/1/properties/error/anyOf/0/properties/tryMessage"
1591415922
},

‎packages/cli/oclif.manifest.json‎

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

‎packages/theme/src/cli/commands/theme/profile.test.ts‎

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import Profile from './profile.js'
22
import {themeProfileJsonOutputSchema, type ThemeProfileResult} from '../../services/profile/types.js'
3+
import * as themeStorage from '../../services/local-storage.js'
34
import {expect, test, vi} from 'vitest'
45
import {withCapturedStandardStreams} from '@shopify/cli-kit/node/testing/output'
6+
import {inTemporaryDirectory} from '@shopify/cli-kit/node/fs'
7+
import {LocalStorage} from '@shopify/cli-kit/node/local-storage'
58

69
vi.mock('../../utilities/theme-selector.js')
710
vi.mock('../../utilities/theme-environment/storefront-renderer.js')
@@ -46,7 +49,7 @@ test('exposes Speedscope evented and sampled profiles while retaining extension
4649
).toThrow()
4750
})
4851

49-
test.each(['profile', 'empty', 'failure', 'invalid result'])(
52+
test.each(['profile', 'empty', 'unknown location', 'fractional location', 'failure', 'invalid result'])(
5053
'keeps %s JSON on stdout and progress events on stderr',
5154
async (mode) => {
5255
const {default: StreamProfile} = await import('./profile.js')
@@ -66,28 +69,47 @@ test.each(['profile', 'empty', 'failure', 'invalid result'])(
6669
processing: false,
6770
createdAtRuntime: false,
6871
})
69-
const result = mode === 'empty' ? {...profile, profiles: [], shared: {frames: []}} : profile
72+
let result = profile
73+
if (mode === 'empty') result = {...profile, profiles: [], shared: {frames: []}}
74+
if (mode === 'unknown location' || mode === 'fractional location') {
75+
const position = mode === 'unknown location' ? -1 : 0.5
76+
result = {...profile, shared: {frames: [{name: 'layout', line: position, col: position}]}}
77+
}
7078
// Keep unusual whitespace and upstream field order to catch accidental reserialization.
7179
const source = mode === 'invalid result' ? '{"profiles":false}' : ` ${JSON.stringify(result, null, 4)}\n`
7280
vi.mocked(render).mockResolvedValue(new Response(source, {status: 200}))
7381
if (mode === 'failure') vi.mocked(render).mockRejectedValue(new Error('Network error'))
74-
await withCapturedStandardStreams(async ({stdout, stderr}) => {
75-
const operation = runWithCommandEventsForCommand(['--json'], () =>
76-
new StreamProfile(['--store=shop.myshopify.com', '--json'], config).run(),
77-
)
78-
if (mode === 'failure') await expect(operation).rejects.toThrow('Network error')
79-
else if (mode === 'invalid result') await expect(operation).rejects.toThrow()
80-
else await operation
81-
expect(openURL).not.toHaveBeenCalled()
82-
const failed = mode === 'failure' || mode === 'invalid result'
83-
expect(stdout()).toBe(failed ? '' : `${source}\n`)
84-
if (!failed) expect(JSON.parse(stdout())).toEqual(result)
85-
const events = stderr()
86-
.trim()
87-
.split('\n')
88-
.map((line) => JSON.parse(line))
89-
expect(events.map((event) => event.status)).toEqual(failed ? ['started', 'failed'] : ['started', 'completed'])
90-
expect(events.every((event) => event.type === 'progress')).toBe(true)
82+
await inTemporaryDirectory(async (directory) => {
83+
const storage = new LocalStorage<themeStorage.ThemeLocalStorageSchema>({cwd: directory})
84+
const {getThemeStore, setThemeStore} = themeStorage
85+
const getStore = vi.spyOn(themeStorage, 'getThemeStore').mockImplementation(() => getThemeStore(storage))
86+
const setStore = vi
87+
.spyOn(themeStorage, 'setThemeStore')
88+
.mockImplementation((store) => setThemeStore(store, storage))
89+
try {
90+
await withCapturedStandardStreams(async ({stdout, stderr}) => {
91+
const operation = runWithCommandEventsForCommand(['--json'], () =>
92+
new StreamProfile(['--store=shop.myshopify.com', '--json'], config).run(),
93+
)
94+
if (mode === 'failure') await expect(operation).rejects.toThrow('Network error')
95+
else if (mode === 'invalid result') await expect(operation).rejects.toThrow()
96+
else await operation
97+
expect(openURL).not.toHaveBeenCalled()
98+
const failed = mode === 'failure' || mode === 'invalid result'
99+
expect(stdout()).toBe(failed ? '' : `${source}\n`)
100+
if (!failed) expect(JSON.parse(stdout())).toEqual(result)
101+
const events = stderr()
102+
.trim()
103+
.split('\n')
104+
.map((line) => JSON.parse(line))
105+
expect(events.map((event) => event.status)).toEqual(failed ? ['started', 'failed'] : ['started', 'completed'])
106+
expect(events.every((event) => event.type === 'progress')).toBe(true)
107+
})
108+
expect(storage.get('themeStore')).toBe('shop.myshopify.com')
109+
} finally {
110+
getStore.mockRestore()
111+
setStore.mockRestore()
112+
}
91113
})
92114
},
93115
)

‎packages/theme/src/cli/commands/theme/profile.ts‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,6 @@ export default class Profile extends ThemeCommand {
7171
return result?.result
7272
}
7373

74-
protected collectsEnvironmentResults(flags: Partial<ProfileFlags>): boolean {
75-
return Boolean(flags.json)
76-
}
77-
7874
protected renderEnvironmentResults(environments: ThemeEnvironmentResult[]): void {
7975
outputResult(themeProfileJsonOutputSchema.encode({environments}))
8076
}

‎packages/theme/src/cli/services/profile.test.ts‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,17 @@ describe('profile', () => {
9090
expect(htmlContent).toContain('speedscope')
9191
})
9292

93+
test.each([-1, 0.5])('opens native profiles with source position %s', async (position) => {
94+
const data = {...mockProfileData, shared: {frames: [{name: 'layout', line: position, col: position}]}}
95+
vi.mocked(render).mockResolvedValue(new Response(JSON.stringify(data), {status: 200}))
96+
97+
const result = await profile(mockAdminSession, themeId, urlPath)
98+
expect(result.result).toEqual(data)
99+
await renderThemeProfileResult(result, 'text')
100+
101+
expect(openURL).toHaveBeenCalledWith(expect.stringMatching(/^file:\/\/.*\.html$/))
102+
})
103+
93104
test('throws error when fetch fails', async () => {
94105
// Given
95106
vi.mocked(render).mockRejectedValue(new Error('Network error'))

‎packages/theme/src/cli/services/profile/types.ts‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ const ProfileFrameSchema = zod
77
.object({
88
name: zod.string(),
99
file: zod.string().optional(),
10-
line: zod.number().int().nonnegative().optional(),
11-
col: zod.number().int().nonnegative().optional(),
10+
line: zod.number().optional(),
11+
col: zod.number().optional(),
1212
})
1313
.passthrough()
1414
const ProfileEventSchema = zod
1515
.object({
1616
type: zod.enum(['O', 'C']),
1717
at: zod.number(),
18-
frame: zod.number().int().nonnegative(),
18+
frame: zod.number(),
1919
})
2020
.passthrough()
2121
const ProfileBaseSchema = zod.object({
@@ -30,7 +30,7 @@ const EventedProfileSchema = ProfileBaseSchema.extend({
3030
}).passthrough()
3131
const SampledProfileSchema = ProfileBaseSchema.extend({
3232
type: zod.literal('sampled'),
33-
samples: zod.array(zod.array(zod.number().int().nonnegative())),
33+
samples: zod.array(zod.array(zod.number())),
3434
weights: zod.array(zod.number()),
3535
}).passthrough()
3636
const ProfileSharedSchema = zod.object({frames: zod.array(ProfileFrameSchema)}).passthrough()
@@ -42,7 +42,7 @@ export const themeProfileResultSchema = zod
4242
profiles: zod.array(zod.discriminatedUnion('type', [EventedProfileSchema, SampledProfileSchema])),
4343
name: zod.string().optional(),
4444
exporter: zod.string().optional(),
45-
activeProfileIndex: zod.number().int().nonnegative().optional(),
45+
activeProfileIndex: zod.number().optional(),
4646
})
4747
.passthrough()
4848
.describe(

0 commit comments

Comments
 (0)