@slicemachine/manager 0.1.1-dev-plugins-validation.0 → 0.1.1-dev-plugins-m2-validation.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth/createPrismicAuthManagerMiddleware.cjs +2 -1
- package/dist/auth/createPrismicAuthManagerMiddleware.cjs.map +1 -1
- package/dist/auth/createPrismicAuthManagerMiddleware.js +2 -1
- package/dist/auth/createPrismicAuthManagerMiddleware.js.map +1 -1
- package/dist/lib/decodeSliceMachineConfig.cjs +0 -1
- package/dist/lib/decodeSliceMachineConfig.cjs.map +1 -1
- package/dist/lib/decodeSliceMachineConfig.js +0 -1
- package/dist/lib/decodeSliceMachineConfig.js.map +1 -1
- package/dist/lib/locateFileUpward.cjs.map +1 -1
- package/dist/lib/locateFileUpward.js.map +1 -1
- package/dist/managers/SliceMachineManager.cjs +34 -20
- package/dist/managers/SliceMachineManager.cjs.map +1 -1
- package/dist/managers/SliceMachineManager.d.ts +0 -2
- package/dist/managers/SliceMachineManager.js +34 -20
- package/dist/managers/SliceMachineManager.js.map +1 -1
- package/dist/managers/prismicRepository/PrismicRepositoryManager.cjs +19 -3
- package/dist/managers/prismicRepository/PrismicRepositoryManager.cjs.map +1 -1
- package/dist/managers/prismicRepository/PrismicRepositoryManager.js +19 -3
- package/dist/managers/prismicRepository/PrismicRepositoryManager.js.map +1 -1
- package/dist/managers/project/ProjectManager.cjs.map +1 -1
- package/dist/managers/project/ProjectManager.js.map +1 -1
- package/dist/managers/screenshots/ScreenshotsManager.cjs +7 -1
- package/dist/managers/screenshots/ScreenshotsManager.cjs.map +1 -1
- package/dist/managers/screenshots/ScreenshotsManager.js +7 -1
- package/dist/managers/screenshots/ScreenshotsManager.js.map +1 -1
- package/dist/managers/slices/SlicesManager.cjs +27 -19
- package/dist/managers/slices/SlicesManager.cjs.map +1 -1
- package/dist/managers/slices/SlicesManager.d.ts +5 -1
- package/dist/managers/slices/SlicesManager.js +27 -19
- package/dist/managers/slices/SlicesManager.js.map +1 -1
- package/dist/managers/telemetry/TelemetryManager.cjs +3 -3
- package/dist/managers/telemetry/TelemetryManager.cjs.map +1 -1
- package/dist/managers/telemetry/TelemetryManager.js +3 -3
- package/dist/managers/telemetry/TelemetryManager.js.map +1 -1
- package/dist/managers/telemetry/types.cjs.map +1 -1
- package/dist/managers/telemetry/types.d.ts +4 -12
- package/dist/managers/telemetry/types.js.map +1 -1
- package/dist/types.d.ts +0 -1
- package/package.json +7 -6
- package/src/auth/createPrismicAuthManagerMiddleware.ts +3 -1
- package/src/lib/decodeSliceMachineConfig.ts +0 -1
- package/src/lib/locateFileUpward.ts +0 -1
- package/src/managers/SliceMachineManager.ts +47 -26
- package/src/managers/prismicRepository/PrismicRepositoryManager.ts +25 -4
- package/src/managers/project/ProjectManager.ts +0 -1
- package/src/managers/screenshots/ScreenshotsManager.ts +11 -1
- package/src/managers/slices/SlicesManager.ts +34 -29
- package/src/managers/telemetry/TelemetryManager.ts +3 -3
- package/src/managers/telemetry/types.ts +6 -9
- package/src/types.ts +0 -2
|
@@ -68,7 +68,6 @@ type CommandInitEndSegmentEvent = SegmentEvent<typeof SegmentEventType.command_i
|
|
|
68
68
|
error?: string;
|
|
69
69
|
}>;
|
|
70
70
|
type ReviewSegmentEvent = SegmentEvent<typeof SegmentEventType.review, {
|
|
71
|
-
framework: string;
|
|
72
71
|
rating: number;
|
|
73
72
|
comment: string;
|
|
74
73
|
}>;
|
|
@@ -80,25 +79,18 @@ type OnboardingContinueScreenIntroSegmentEvent = SegmentEvent<typeof SegmentEven
|
|
|
80
79
|
type OnboardingContinueScreen1SegmentEvent = SegmentEvent<typeof SegmentEventType.onboarding_continue_screen1>;
|
|
81
80
|
type OnboardingContinueScreen2SegmentEvent = SegmentEvent<typeof SegmentEventType.onboarding_continue_screen2>;
|
|
82
81
|
type OnboardingContinueScreen3SegmentEvent = SegmentEvent<typeof SegmentEventType.onboarding_continue_screen3>;
|
|
83
|
-
type SliceSimulatorSetupSegmentEvent = SegmentEvent<typeof SegmentEventType.sliceSimulator_setup
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
type SliceSimulatorOpenSegmentEvent = SegmentEvent<typeof SegmentEventType.sliceSimulator_open, {
|
|
87
|
-
framework: string;
|
|
88
|
-
}>;
|
|
89
|
-
type SliceSimulatorIsNotRunningSegmentEvent = SegmentEvent<typeof SegmentEventType.sliceSimulator_isNotRunning, {
|
|
90
|
-
framework: string;
|
|
91
|
-
}>;
|
|
82
|
+
type SliceSimulatorSetupSegmentEvent = SegmentEvent<typeof SegmentEventType.sliceSimulator_setup>;
|
|
83
|
+
type SliceSimulatorOpenSegmentEvent = SegmentEvent<typeof SegmentEventType.sliceSimulator_open>;
|
|
84
|
+
type SliceSimulatorIsNotRunningSegmentEvent = SegmentEvent<typeof SegmentEventType.sliceSimulator_isNotRunning>;
|
|
92
85
|
type PageViewSegmentEvent = SegmentEvent<typeof SegmentEventType.pageView, {
|
|
93
86
|
url: string;
|
|
94
87
|
path: string;
|
|
95
88
|
search: string;
|
|
96
89
|
title: string;
|
|
97
90
|
referrer: string;
|
|
98
|
-
|
|
91
|
+
adapter: string;
|
|
99
92
|
}>;
|
|
100
93
|
type OpenVideoTutorialsSegmentEvent = SegmentEvent<typeof SegmentEventType.openVideoTutorials, {
|
|
101
|
-
framework: string;
|
|
102
94
|
video: string;
|
|
103
95
|
}>;
|
|
104
96
|
type CustomTypeCreatedSegmentEvent = SegmentEvent<typeof SegmentEventType.customType_created, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sources":["../../../../src/managers/telemetry/types.ts"],"sourcesContent":["import type { LimitType } from \"../prismicRepository/types\";\n\nexport const SegmentEventType = {\n\tcommand_init_start: \"command:init:start\",\n\tcommand_init_identify: \"command:init:identify\",\n\tcommand_init_end: \"command:init:end\",\n\treview: \"review\",\n\tonboarding_start: \"onboarding:start\",\n\tonboarding_skip: \"onboarding:skip\",\n\tonboarding_continue_screenIntro: \"onboarding:continue:screen-intro\",\n\tonboarding_continue_screen1: \"onboarding:continue:screen-1\",\n\tonboarding_continue_screen2: \"onboarding:continue:screen-2\",\n\tonboarding_continue_screen3: \"onboarding:continue:screen-3\",\n\tsliceSimulator_setup: \"slice-simulator:setup\",\n\tsliceSimulator_open: \"slice-simulator:open\",\n\tsliceSimulator_isNotRunning: \"slice-simulator:is-not-running\",\n\tpageView: \"page-view\",\n\topenVideoTutorials: \"open-video-tutorials\",\n\tcustomType_created: \"custom-type:created\",\n\tcustomType_fieldAdded: \"custom-type:field-added\",\n\tcustomType_sliceZoneUpdated: \"custom-type:slice-zone-updated\",\n\tcustomType_saved: \"custom-type:saved\",\n\tslice_created: \"slice:created\",\n\tscreenshotTaken: \"screenshot-taken\",\n\tchanges_pushed: \"changes:pushed\",\n\tchanges_limitReach: \"changes:limit-reach\",\n\teditor_widgetUsed: \"editor:widget-used\",\n} as const;\ntype SegmentEventTypes =\n\t(typeof SegmentEventType)[keyof typeof SegmentEventType];\n\nexport const HumanSegmentEventType = {\n\t[SegmentEventType.command_init_start]: \"SliceMachine Init Start\",\n\t[SegmentEventType.command_init_identify]: \"SliceMachine Init Identify\",\n\t[SegmentEventType.command_init_end]: \"SliceMachine Init End\",\n\t[SegmentEventType.review]: \"SliceMachine Review\",\n\t[SegmentEventType.onboarding_start]: \"SliceMachine Onboarding Start\",\n\t[SegmentEventType.onboarding_skip]: \"SliceMachine Onboarding Skip\",\n\t[SegmentEventType.onboarding_continue_screenIntro]:\n\t\t\"SliceMachine Onboarding Continue Screen Intro\",\n\t[SegmentEventType.onboarding_continue_screen1]:\n\t\t\"SliceMachine Onboarding Continue Screen 1\",\n\t[SegmentEventType.onboarding_continue_screen2]:\n\t\t\"SliceMachine Onboarding Continue Screen 2\",\n\t[SegmentEventType.onboarding_continue_screen3]:\n\t\t\"SliceMachine Onboarding Continue Screen 3\",\n\t[SegmentEventType.sliceSimulator_setup]: \"SliceMachine Slice Simulator Setup\",\n\t[SegmentEventType.sliceSimulator_open]: \"SliceMachine Slice Simulator Open\",\n\t[SegmentEventType.sliceSimulator_isNotRunning]:\n\t\t\"SliceMachine Slice Simulator is not running\",\n\t[SegmentEventType.pageView]: \"SliceMachine Page View\",\n\t[SegmentEventType.openVideoTutorials]: \"SliceMachine Open Video Tutorials\",\n\t[SegmentEventType.customType_created]: \"SliceMachine Custom Type Created\",\n\t[SegmentEventType.customType_fieldAdded]:\n\t\t\"SliceMachine Custom Type Field Added\",\n\t[SegmentEventType.customType_sliceZoneUpdated]:\n\t\t\"SliceMachine Slicezone Updated\",\n\t[SegmentEventType.customType_saved]: \"SliceMachine Custom Type Saved\",\n\t[SegmentEventType.slice_created]: \"SliceMachine Slice Created\",\n\t[SegmentEventType.screenshotTaken]: \"SliceMachine Screenshot Taken\",\n\t[SegmentEventType.changes_pushed]: \"SliceMachine Changes Pushed\",\n\t[SegmentEventType.changes_limitReach]: \"SliceMachine Changes Limit Reach\",\n\t[SegmentEventType.editor_widgetUsed]: \"SliceMachine Editor Widget Used\",\n} as const;\nexport type HumanSegmentEventTypes =\n\t(typeof HumanSegmentEventType)[keyof typeof HumanSegmentEventType];\n\ntype SegmentEvent<\n\tTType extends SegmentEventTypes,\n\tTProperties extends Record<string, unknown> | void = void,\n> = TProperties extends void\n\t? {\n\t\t\tevent: TType;\n\t\t\trepository?: string;\n\t }\n\t: {\n\t\t\tevent: TType;\n\t\t\trepository?: string;\n\t } & TProperties;\n\ntype CommandInitStartSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.command_init_start\n>;\n\n// This event feels off, we have a dedicated `identify` method...\ntype CommandInitIdentifySegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.command_init_identify\n>;\n\ntype CommandInitEndSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.command_init_end,\n\t{ framework: string; success: boolean; error?: string }\n>;\n\ntype ReviewSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.review,\n\t{
|
|
1
|
+
{"version":3,"file":"types.js","sources":["../../../../src/managers/telemetry/types.ts"],"sourcesContent":["import type { LimitType } from \"../prismicRepository/types\";\n\nexport const SegmentEventType = {\n\tcommand_init_start: \"command:init:start\",\n\tcommand_init_identify: \"command:init:identify\",\n\tcommand_init_end: \"command:init:end\",\n\treview: \"review\",\n\tonboarding_start: \"onboarding:start\",\n\tonboarding_skip: \"onboarding:skip\",\n\tonboarding_continue_screenIntro: \"onboarding:continue:screen-intro\",\n\tonboarding_continue_screen1: \"onboarding:continue:screen-1\",\n\tonboarding_continue_screen2: \"onboarding:continue:screen-2\",\n\tonboarding_continue_screen3: \"onboarding:continue:screen-3\",\n\tsliceSimulator_setup: \"slice-simulator:setup\",\n\tsliceSimulator_open: \"slice-simulator:open\",\n\tsliceSimulator_isNotRunning: \"slice-simulator:is-not-running\",\n\tpageView: \"page-view\",\n\topenVideoTutorials: \"open-video-tutorials\",\n\tcustomType_created: \"custom-type:created\",\n\tcustomType_fieldAdded: \"custom-type:field-added\",\n\tcustomType_sliceZoneUpdated: \"custom-type:slice-zone-updated\",\n\tcustomType_saved: \"custom-type:saved\",\n\tslice_created: \"slice:created\",\n\tscreenshotTaken: \"screenshot-taken\",\n\tchanges_pushed: \"changes:pushed\",\n\tchanges_limitReach: \"changes:limit-reach\",\n\teditor_widgetUsed: \"editor:widget-used\",\n} as const;\ntype SegmentEventTypes =\n\t(typeof SegmentEventType)[keyof typeof SegmentEventType];\n\nexport const HumanSegmentEventType = {\n\t[SegmentEventType.command_init_start]: \"SliceMachine Init Start\",\n\t[SegmentEventType.command_init_identify]: \"SliceMachine Init Identify\",\n\t[SegmentEventType.command_init_end]: \"SliceMachine Init End\",\n\t[SegmentEventType.review]: \"SliceMachine Review\",\n\t[SegmentEventType.onboarding_start]: \"SliceMachine Onboarding Start\",\n\t[SegmentEventType.onboarding_skip]: \"SliceMachine Onboarding Skip\",\n\t[SegmentEventType.onboarding_continue_screenIntro]:\n\t\t\"SliceMachine Onboarding Continue Screen Intro\",\n\t[SegmentEventType.onboarding_continue_screen1]:\n\t\t\"SliceMachine Onboarding Continue Screen 1\",\n\t[SegmentEventType.onboarding_continue_screen2]:\n\t\t\"SliceMachine Onboarding Continue Screen 2\",\n\t[SegmentEventType.onboarding_continue_screen3]:\n\t\t\"SliceMachine Onboarding Continue Screen 3\",\n\t[SegmentEventType.sliceSimulator_setup]: \"SliceMachine Slice Simulator Setup\",\n\t[SegmentEventType.sliceSimulator_open]: \"SliceMachine Slice Simulator Open\",\n\t[SegmentEventType.sliceSimulator_isNotRunning]:\n\t\t\"SliceMachine Slice Simulator is not running\",\n\t[SegmentEventType.pageView]: \"SliceMachine Page View\",\n\t[SegmentEventType.openVideoTutorials]: \"SliceMachine Open Video Tutorials\",\n\t[SegmentEventType.customType_created]: \"SliceMachine Custom Type Created\",\n\t[SegmentEventType.customType_fieldAdded]:\n\t\t\"SliceMachine Custom Type Field Added\",\n\t[SegmentEventType.customType_sliceZoneUpdated]:\n\t\t\"SliceMachine Slicezone Updated\",\n\t[SegmentEventType.customType_saved]: \"SliceMachine Custom Type Saved\",\n\t[SegmentEventType.slice_created]: \"SliceMachine Slice Created\",\n\t[SegmentEventType.screenshotTaken]: \"SliceMachine Screenshot Taken\",\n\t[SegmentEventType.changes_pushed]: \"SliceMachine Changes Pushed\",\n\t[SegmentEventType.changes_limitReach]: \"SliceMachine Changes Limit Reach\",\n\t[SegmentEventType.editor_widgetUsed]: \"SliceMachine Editor Widget Used\",\n} as const;\nexport type HumanSegmentEventTypes =\n\t(typeof HumanSegmentEventType)[keyof typeof HumanSegmentEventType];\n\ntype SegmentEvent<\n\tTType extends SegmentEventTypes,\n\tTProperties extends Record<string, unknown> | void = void,\n> = TProperties extends void\n\t? {\n\t\t\tevent: TType;\n\t\t\trepository?: string;\n\t }\n\t: {\n\t\t\tevent: TType;\n\t\t\trepository?: string;\n\t } & TProperties;\n\ntype CommandInitStartSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.command_init_start\n>;\n\n// This event feels off, we have a dedicated `identify` method...\ntype CommandInitIdentifySegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.command_init_identify\n>;\n\ntype CommandInitEndSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.command_init_end,\n\t{ framework: string; success: boolean; error?: string }\n>;\n\ntype ReviewSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.review,\n\t{ rating: number; comment: string }\n>;\n\ntype OnboardingStartSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.onboarding_start\n>;\n\ntype OnboardingSkipSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.onboarding_skip,\n\t{ screenSkipped: number }\n>;\n\ntype OnboardingContinueScreenIntroSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.onboarding_continue_screenIntro\n>;\n\ntype OnboardingContinueScreen1SegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.onboarding_continue_screen1\n>;\n\ntype OnboardingContinueScreen2SegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.onboarding_continue_screen2\n>;\n\ntype OnboardingContinueScreen3SegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.onboarding_continue_screen3\n>;\n\ntype SliceSimulatorSetupSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.sliceSimulator_setup\n>;\n\ntype SliceSimulatorOpenSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.sliceSimulator_open\n>;\n\ntype SliceSimulatorIsNotRunningSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.sliceSimulator_isNotRunning\n>;\n\ntype PageViewSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.pageView,\n\t{\n\t\turl: string;\n\t\tpath: string;\n\t\tsearch: string;\n\t\ttitle: string;\n\t\treferrer: string;\n\t\tadapter: string;\n\t}\n>;\n\ntype OpenVideoTutorialsSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.openVideoTutorials,\n\t{ video: string }\n>;\n\ntype CustomTypeCreatedSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.customType_created,\n\t{ id: string; name: string; type: \"repeatable\" | \"single\" }\n>;\n\ntype CustomTypeFieldAddedSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.customType_fieldAdded,\n\t{\n\t\tid: string; // field id\n\t\tname: string; // custom type id\n\t\tzone: \"static\" | \"repeatable\";\n\t\ttype: string;\n\t}\n>;\n\ntype CustomTypeSliceZoneUpdatedSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.customType_sliceZoneUpdated,\n\t{ customTypeId: string }\n>;\n\ntype CustomTypeSavedSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.customType_saved,\n\t{ id: string; name: string; type: \"repeatable\" | \"single\" }\n>;\n\ntype SliceCreatedSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.slice_created,\n\t{ id: string; name: string; library: string }\n>;\n\ntype ScreenshotTakenSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.screenshotTaken,\n\t{\n\t\ttype: \"custom\" | \"automatic\";\n\t\tmethod: \"fromSimulator\" | \"upload\" | \"dragAndDrop\";\n\t}\n>;\n\ntype ChangesPushedSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.changes_pushed,\n\t{\n\t\tcustomTypesCreated: number;\n\t\tcustomTypesModified: number;\n\t\tcustomTypesDeleted: number;\n\t\tslicesCreated: number;\n\t\tslicesModified: number;\n\t\tslicesDeleted: number;\n\t\tmissingScreenshots: number;\n\t\ttotal: number;\n\t\tduration: number;\n\t\thasDeletedDocuments: boolean;\n\t}\n>;\n\ntype ChangesLimitReachSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.changes_limitReach,\n\t{ limitType: LimitType }\n>;\n\ntype EditorWidgetUsedSegmentEvent = SegmentEvent<\n\ttypeof SegmentEventType.editor_widgetUsed,\n\t{ sliceId: string }\n>;\n\nexport type SegmentEvents =\n\t| CommandInitStartSegmentEvent\n\t| CommandInitIdentifySegmentEvent\n\t| CommandInitEndSegmentEvent\n\t| ReviewSegmentEvent\n\t| OnboardingStartSegmentEvent\n\t| OnboardingSkipSegmentEvent\n\t| OnboardingContinueScreenIntroSegmentEvent\n\t| OnboardingContinueScreen1SegmentEvent\n\t| OnboardingContinueScreen2SegmentEvent\n\t| OnboardingContinueScreen3SegmentEvent\n\t| SliceSimulatorSetupSegmentEvent\n\t| SliceSimulatorOpenSegmentEvent\n\t| SliceSimulatorIsNotRunningSegmentEvent\n\t| PageViewSegmentEvent\n\t| OpenVideoTutorialsSegmentEvent\n\t| CustomTypeCreatedSegmentEvent\n\t| CustomTypeFieldAddedSegmentEvent\n\t| CustomTypeSliceZoneUpdatedSegmentEvent\n\t| CustomTypeSavedSegmentEvent\n\t| SliceCreatedSegmentEvent\n\t| ScreenshotTakenSegmentEvent\n\t| ChangesPushedSegmentEvent\n\t| ChangesLimitReachSegmentEvent\n\t| EditorWidgetUsedSegmentEvent;\n"],"names":[],"mappings":"AAEO,MAAM,mBAAmB;AAAA,EAC/B,oBAAoB;AAAA,EACpB,uBAAuB;AAAA,EACvB,kBAAkB;AAAA,EAClB,QAAQ;AAAA,EACR,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,iCAAiC;AAAA,EACjC,6BAA6B;AAAA,EAC7B,6BAA6B;AAAA,EAC7B,6BAA6B;AAAA,EAC7B,sBAAsB;AAAA,EACtB,qBAAqB;AAAA,EACrB,6BAA6B;AAAA,EAC7B,UAAU;AAAA,EACV,oBAAoB;AAAA,EACpB,oBAAoB;AAAA,EACpB,uBAAuB;AAAA,EACvB,6BAA6B;AAAA,EAC7B,kBAAkB;AAAA,EAClB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,mBAAmB;;AAKb,MAAM,wBAAwB;AAAA,EACpC,CAAC,iBAAiB,kBAAkB,GAAG;AAAA,EACvC,CAAC,iBAAiB,qBAAqB,GAAG;AAAA,EAC1C,CAAC,iBAAiB,gBAAgB,GAAG;AAAA,EACrC,CAAC,iBAAiB,MAAM,GAAG;AAAA,EAC3B,CAAC,iBAAiB,gBAAgB,GAAG;AAAA,EACrC,CAAC,iBAAiB,eAAe,GAAG;AAAA,EACpC,CAAC,iBAAiB,+BAA+B,GAChD;AAAA,EACD,CAAC,iBAAiB,2BAA2B,GAC5C;AAAA,EACD,CAAC,iBAAiB,2BAA2B,GAC5C;AAAA,EACD,CAAC,iBAAiB,2BAA2B,GAC5C;AAAA,EACD,CAAC,iBAAiB,oBAAoB,GAAG;AAAA,EACzC,CAAC,iBAAiB,mBAAmB,GAAG;AAAA,EACxC,CAAC,iBAAiB,2BAA2B,GAC5C;AAAA,EACD,CAAC,iBAAiB,QAAQ,GAAG;AAAA,EAC7B,CAAC,iBAAiB,kBAAkB,GAAG;AAAA,EACvC,CAAC,iBAAiB,kBAAkB,GAAG;AAAA,EACvC,CAAC,iBAAiB,qBAAqB,GACtC;AAAA,EACD,CAAC,iBAAiB,2BAA2B,GAC5C;AAAA,EACD,CAAC,iBAAiB,gBAAgB,GAAG;AAAA,EACrC,CAAC,iBAAiB,aAAa,GAAG;AAAA,EAClC,CAAC,iBAAiB,eAAe,GAAG;AAAA,EACpC,CAAC,iBAAiB,cAAc,GAAG;AAAA,EACnC,CAAC,iBAAiB,kBAAkB,GAAG;AAAA,EACvC,CAAC,iBAAiB,iBAAiB,GAAG;;"}
|
package/dist/types.d.ts
CHANGED
|
@@ -26,7 +26,6 @@ export type SliceMachineConfigPluginRegistration<TSliceMachinePluginOptions exte
|
|
|
26
26
|
* Slice Machine configuration from `slicemachine.config.js`.
|
|
27
27
|
*/
|
|
28
28
|
export type SliceMachineConfig = {
|
|
29
|
-
_latest: string;
|
|
30
29
|
apiEndpoint?: string;
|
|
31
30
|
repositoryName: string;
|
|
32
31
|
localSliceSimulatorURL?: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slicemachine/manager",
|
|
3
|
-
"version": "0.1.1-dev-plugins-validation.0",
|
|
3
|
+
"version": "0.1.1-dev-plugins-m2-validation.0",
|
|
4
4
|
"description": "Manage all aspects of a Slice Machine project.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -47,10 +47,10 @@
|
|
|
47
47
|
],
|
|
48
48
|
"scripts": {
|
|
49
49
|
"build": "vite build",
|
|
50
|
-
"dev": "vite build --watch",
|
|
50
|
+
"dev": "vite build --watch --mode development",
|
|
51
51
|
"format": "prettier --write .",
|
|
52
52
|
"lint": "eslint --ext .js,.ts .",
|
|
53
|
-
"
|
|
53
|
+
"prepublishOnly": "npm run build",
|
|
54
54
|
"size": "size-limit",
|
|
55
55
|
"test": "npm run lint && npm run types && npm run unit && npm run build && npm run size",
|
|
56
56
|
"types": "tsc --noEmit",
|
|
@@ -61,9 +61,9 @@
|
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"@antfu/ni": "^0.20.0",
|
|
64
|
-
"@prismicio/custom-types-client": "^1.0
|
|
64
|
+
"@prismicio/custom-types-client": "^1.1.0",
|
|
65
65
|
"@prismicio/types-internal": "^1.5.3",
|
|
66
|
-
"@slicemachine/plugin-kit": "0.1.8-dev-plugins-validation.0",
|
|
66
|
+
"@slicemachine/plugin-kit": "0.1.8-dev-plugins-m2-validation.0",
|
|
67
67
|
"@wooorm/starry-night": "^1.6.0",
|
|
68
68
|
"analytics-node": "^6.2.0",
|
|
69
69
|
"cookie": "^0.5.0",
|
|
@@ -100,6 +100,7 @@
|
|
|
100
100
|
"@typescript-eslint/parser": "^5.55.0",
|
|
101
101
|
"@vitest/coverage-c8": "^0.27.3",
|
|
102
102
|
"better-npm-audit": "^3.7.3",
|
|
103
|
+
"depcheck": "^1.4.3",
|
|
103
104
|
"eslint": "^8.36.0",
|
|
104
105
|
"eslint-config-prettier": "^8.7.0",
|
|
105
106
|
"eslint-plugin-prettier": "^4.2.1",
|
|
@@ -135,5 +136,5 @@
|
|
|
135
136
|
"publishConfig": {
|
|
136
137
|
"access": "public"
|
|
137
138
|
},
|
|
138
|
-
"gitHead": "
|
|
139
|
+
"gitHead": "f2b7a99b811ce7bef307e38a39158132b66b43f3"
|
|
139
140
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { CustomTypes } from "@prismicio/types-internal";
|
|
2
2
|
import { SharedSliceContent } from "@prismicio/types-internal/lib/content";
|
|
3
|
+
import {
|
|
4
|
+
ForbiddenError,
|
|
5
|
+
UnauthorizedError,
|
|
6
|
+
} from "@prismicio/custom-types-client";
|
|
3
7
|
import {
|
|
4
8
|
SliceMachinePlugin,
|
|
5
9
|
SliceMachinePluginRunner,
|
|
@@ -44,7 +48,6 @@ type SliceMachineManagerGetStateReturnType = {
|
|
|
44
48
|
repo: string;
|
|
45
49
|
changelog?: PackageChangelog;
|
|
46
50
|
packageManager: PackageManager;
|
|
47
|
-
framework: unknown; // TODO: Remove
|
|
48
51
|
};
|
|
49
52
|
libraries: {
|
|
50
53
|
name: string;
|
|
@@ -60,7 +63,6 @@ type SliceMachineManagerGetStateReturnType = {
|
|
|
60
63
|
screenshots: Record<
|
|
61
64
|
string,
|
|
62
65
|
{
|
|
63
|
-
path: string;
|
|
64
66
|
hash: string;
|
|
65
67
|
data: Buffer;
|
|
66
68
|
}
|
|
@@ -165,7 +167,7 @@ export class SliceMachineManager {
|
|
|
165
167
|
async getState(): Promise<SliceMachineManagerGetStateReturnType> {
|
|
166
168
|
const [
|
|
167
169
|
{ sliceMachineConfig, libraries },
|
|
168
|
-
{ profile, remoteCustomTypes, remoteSlices },
|
|
170
|
+
{ profile, remoteCustomTypes, remoteSlices, authError },
|
|
169
171
|
customTypes,
|
|
170
172
|
packageManager,
|
|
171
173
|
] = await Promise.all([
|
|
@@ -175,46 +177,66 @@ export class SliceMachineManager {
|
|
|
175
177
|
return { sliceMachineConfig, libraries };
|
|
176
178
|
}),
|
|
177
179
|
this._getProfile().then(async (profile) => {
|
|
180
|
+
let authError;
|
|
178
181
|
if (profile) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
182
|
+
try {
|
|
183
|
+
const [remoteCustomTypes, remoteSlices] = await Promise.all([
|
|
184
|
+
this.customTypes.fetchRemoteCustomTypes(),
|
|
185
|
+
this.slices.fetchRemoteSlices(),
|
|
186
|
+
]);
|
|
187
|
+
|
|
188
|
+
return {
|
|
189
|
+
profile,
|
|
190
|
+
remoteCustomTypes,
|
|
191
|
+
remoteSlices,
|
|
192
|
+
authError,
|
|
193
|
+
};
|
|
194
|
+
} catch (error) {
|
|
195
|
+
// Non-Prismic error
|
|
196
|
+
if (
|
|
197
|
+
error instanceof UnauthorizedError ||
|
|
198
|
+
error instanceof ForbiddenError
|
|
199
|
+
) {
|
|
200
|
+
authError = {
|
|
201
|
+
name: "__stub__",
|
|
202
|
+
message: "__stub__",
|
|
203
|
+
reason: "__stub__",
|
|
204
|
+
status: 401,
|
|
205
|
+
};
|
|
206
|
+
} else {
|
|
207
|
+
throw error;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
195
210
|
}
|
|
211
|
+
|
|
212
|
+
return {
|
|
213
|
+
profile,
|
|
214
|
+
remoteCustomTypes: [],
|
|
215
|
+
remoteSlices: [],
|
|
216
|
+
authError,
|
|
217
|
+
};
|
|
196
218
|
}),
|
|
197
219
|
this._getCustomTypes(),
|
|
198
220
|
this.project.detectPackageManager(),
|
|
199
221
|
]);
|
|
200
222
|
|
|
201
|
-
//
|
|
223
|
+
// SM UI detects if a user is logged out by looking at
|
|
202
224
|
// `clientError`. Here, we simulate what the old core does by
|
|
203
|
-
// returning an `ErrorWithStatus`-like object if the user
|
|
204
|
-
// not logged in.
|
|
225
|
+
// returning an `ErrorWithStatus`-like object if the user does
|
|
226
|
+
// not have access to the repository or is not logged in.
|
|
205
227
|
const clientError: SliceMachineManagerGetStateReturnType["clientError"] =
|
|
206
|
-
|
|
228
|
+
authError ||
|
|
229
|
+
(profile
|
|
207
230
|
? undefined
|
|
208
231
|
: {
|
|
209
232
|
name: "__stub__",
|
|
210
233
|
message: "__stub__",
|
|
211
234
|
reason: "__stub__",
|
|
212
235
|
status: 401, // Needed to trigger the unauthorized flow.
|
|
213
|
-
};
|
|
236
|
+
});
|
|
214
237
|
|
|
215
238
|
return {
|
|
216
239
|
env: {
|
|
217
|
-
framework: "",
|
|
218
240
|
manifest: {
|
|
219
241
|
apiEndpoint:
|
|
220
242
|
sliceMachineConfig.apiEndpoint ||
|
|
@@ -285,7 +307,6 @@ export class SliceMachineManager {
|
|
|
285
307
|
|
|
286
308
|
if (screenshot.data) {
|
|
287
309
|
screenshots[variation.id] = {
|
|
288
|
-
path: "__stub__",
|
|
289
310
|
hash: createContentDigest(screenshot.data),
|
|
290
311
|
data: screenshot.data,
|
|
291
312
|
};
|
|
@@ -273,10 +273,21 @@ export class PrismicRepositoryManager extends BaseManager {
|
|
|
273
273
|
throw Error(`Could not find model ${change.id}`);
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
+
const modelWithScreenshots =
|
|
277
|
+
await this.slices.updateSliceModelScreenshotsInPlace({
|
|
278
|
+
libraryID: change.libraryID,
|
|
279
|
+
model,
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
await this.slices.updateSlice({
|
|
283
|
+
libraryID: change.libraryID,
|
|
284
|
+
model: modelWithScreenshots,
|
|
285
|
+
});
|
|
286
|
+
|
|
276
287
|
return {
|
|
277
288
|
type: ChangeTypes.SLICE_INSERT,
|
|
278
289
|
id: change.id,
|
|
279
|
-
payload:
|
|
290
|
+
payload: modelWithScreenshots,
|
|
280
291
|
};
|
|
281
292
|
}
|
|
282
293
|
case "MODIFIED": {
|
|
@@ -289,10 +300,21 @@ export class PrismicRepositoryManager extends BaseManager {
|
|
|
289
300
|
throw Error(`Could not find model ${change.id}`);
|
|
290
301
|
}
|
|
291
302
|
|
|
303
|
+
const modelWithScreenshots =
|
|
304
|
+
await this.slices.updateSliceModelScreenshotsInPlace({
|
|
305
|
+
libraryID: change.libraryID,
|
|
306
|
+
model,
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
await this.slices.updateSlice({
|
|
310
|
+
libraryID: change.libraryID,
|
|
311
|
+
model: modelWithScreenshots,
|
|
312
|
+
});
|
|
313
|
+
|
|
292
314
|
return {
|
|
293
315
|
type: ChangeTypes.SLICE_UPDATE,
|
|
294
316
|
id: change.id,
|
|
295
|
-
payload:
|
|
317
|
+
payload: modelWithScreenshots,
|
|
296
318
|
};
|
|
297
319
|
}
|
|
298
320
|
case "DELETED":
|
|
@@ -352,9 +374,8 @@ export class PrismicRepositoryManager extends BaseManager {
|
|
|
352
374
|
const authenticationToken = await this.user.getAuthenticationToken();
|
|
353
375
|
const sliceMachineConfig = await this.project.getSliceMachineConfig();
|
|
354
376
|
|
|
355
|
-
// TODO: API route in consts ends with /customtypes
|
|
356
377
|
// TODO: move to customtypes client
|
|
357
|
-
return fetch("
|
|
378
|
+
return fetch(new URL("/bulk", API_ENDPOINTS.PrismicModels).toString(), {
|
|
358
379
|
body: JSON.stringify(requestBody),
|
|
359
380
|
method: "POST",
|
|
360
381
|
headers: {
|
|
@@ -147,7 +147,6 @@ export class ProjectManager extends BaseManager {
|
|
|
147
147
|
async loadSliceMachineConfig(): Promise<SliceMachineConfig> {
|
|
148
148
|
// TODO: Reload plugins with a fresh plugin runner. Plugins may
|
|
149
149
|
// have been added or removed.
|
|
150
|
-
|
|
151
150
|
const configFilePath = await this.getSliceMachineConfigPath();
|
|
152
151
|
|
|
153
152
|
let rawConfig: unknown | undefined;
|
|
@@ -123,7 +123,17 @@ export class ScreenshotsManager extends BaseManager {
|
|
|
123
123
|
Repository: sliceMachineConfig.repositoryName,
|
|
124
124
|
},
|
|
125
125
|
});
|
|
126
|
-
|
|
126
|
+
|
|
127
|
+
const awsACLText = await awsACLRes.text();
|
|
128
|
+
let awsACLJSON: unknown;
|
|
129
|
+
try {
|
|
130
|
+
awsACLJSON = JSON.parse(awsACLText);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
// Response is not JSON
|
|
133
|
+
throw new Error(
|
|
134
|
+
`Invalid AWS ACL response from ${awsACLURL}: ${awsACLText}`,
|
|
135
|
+
);
|
|
136
|
+
}
|
|
127
137
|
|
|
128
138
|
const { value: awsACL, error } = decode(
|
|
129
139
|
t.intersection([
|
|
@@ -30,6 +30,7 @@ import { API_ENDPOINTS } from "../../constants/API_ENDPOINTS";
|
|
|
30
30
|
import { UnauthenticatedError, UnauthorizedError } from "../../errors";
|
|
31
31
|
|
|
32
32
|
import { BaseManager } from "../BaseManager";
|
|
33
|
+
import { createContentDigest } from "../../lib/createContentDigest";
|
|
33
34
|
|
|
34
35
|
type SlicesManagerReadSliceLibraryReturnType = {
|
|
35
36
|
sliceIDs: string[];
|
|
@@ -348,7 +349,7 @@ export class SlicesManager extends BaseManager {
|
|
|
348
349
|
|
|
349
350
|
if (model) {
|
|
350
351
|
const modelWithScreenshots =
|
|
351
|
-
await this.
|
|
352
|
+
await this.updateSliceModelScreenshotsInPlace({
|
|
352
353
|
libraryID: args.libraryID,
|
|
353
354
|
model,
|
|
354
355
|
});
|
|
@@ -568,48 +569,52 @@ export class SlicesManager extends BaseManager {
|
|
|
568
569
|
return await client.getAllSharedSlices();
|
|
569
570
|
}
|
|
570
571
|
|
|
571
|
-
|
|
572
|
+
async updateSliceModelScreenshotsInPlace(
|
|
572
573
|
args: SlicesManagerUpsertHostedSliceScrenshotsArgs,
|
|
573
574
|
): Promise<CustomTypes.Widgets.Slices.SharedSlice> {
|
|
574
575
|
const sliceMachineConfig = await this.project.getSliceMachineConfig();
|
|
575
576
|
|
|
576
577
|
const variations = await Promise.all(
|
|
577
578
|
args.model.variations.map(async (variation) => {
|
|
578
|
-
const updatedVariation: CustomTypes.Widgets.Slices.Variation = {
|
|
579
|
-
...variation,
|
|
580
|
-
imageUrl: DEFAULT_SLICE_SCREENSHOT_URL,
|
|
581
|
-
};
|
|
582
|
-
|
|
583
579
|
const screenshot = await this.readSliceScreenshot({
|
|
584
580
|
libraryID: args.libraryID,
|
|
585
581
|
sliceID: args.model.id,
|
|
586
582
|
variationID: variation.id,
|
|
587
583
|
});
|
|
588
584
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
const uploadedScreenshot = await this.screenshots.uploadScreenshot({
|
|
605
|
-
data: screenshot.data,
|
|
606
|
-
keyPrefix,
|
|
607
|
-
});
|
|
608
|
-
|
|
609
|
-
updatedVariation.imageUrl = uploadedScreenshot.url;
|
|
585
|
+
// If there's no screenshot, delete it by replacing it with the default screenshot
|
|
586
|
+
if (!screenshot.data) {
|
|
587
|
+
return {
|
|
588
|
+
...variation,
|
|
589
|
+
imageUrl: DEFAULT_SLICE_SCREENSHOT_URL,
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
const hasScreenshotChanged = !variation.imageUrl?.includes(
|
|
594
|
+
createContentDigest(screenshot.data),
|
|
595
|
+
);
|
|
596
|
+
|
|
597
|
+
// If screenshot hasn't changed, do nothing
|
|
598
|
+
if (!hasScreenshotChanged) {
|
|
599
|
+
return variation;
|
|
610
600
|
}
|
|
611
601
|
|
|
612
|
-
|
|
602
|
+
const keyPrefix = [
|
|
603
|
+
sliceMachineConfig.repositoryName,
|
|
604
|
+
"shared-slices",
|
|
605
|
+
args.model.id,
|
|
606
|
+
variation.id,
|
|
607
|
+
].join("/");
|
|
608
|
+
|
|
609
|
+
const uploadedScreenshot = await this.screenshots.uploadScreenshot({
|
|
610
|
+
data: screenshot.data,
|
|
611
|
+
keyPrefix,
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
return {
|
|
615
|
+
...variation,
|
|
616
|
+
imageUrl: uploadedScreenshot.url,
|
|
617
|
+
};
|
|
613
618
|
}),
|
|
614
619
|
);
|
|
615
620
|
|
|
@@ -123,7 +123,7 @@ export class TelemetryManager extends BaseManager {
|
|
|
123
123
|
this._segmentClient.track(
|
|
124
124
|
payload as Parameters<typeof this._segmentClient.track>[0],
|
|
125
125
|
(maybeError?: Error) => {
|
|
126
|
-
if (maybeError) {
|
|
126
|
+
if (maybeError && import.meta.env.DEV) {
|
|
127
127
|
// TODO: Not sure how we want to deal with that
|
|
128
128
|
console.warn(
|
|
129
129
|
`An error occurred during Segment tracking`,
|
|
@@ -159,7 +159,7 @@ export class TelemetryManager extends BaseManager {
|
|
|
159
159
|
|
|
160
160
|
// TODO: Make sure client fails gracefully when no internet connection
|
|
161
161
|
this._segmentClient.identify(payload, (maybeError?: Error) => {
|
|
162
|
-
if (maybeError) {
|
|
162
|
+
if (maybeError && import.meta.env.DEV) {
|
|
163
163
|
// TODO: Not sure how we want to deal with that
|
|
164
164
|
console.warn(`An error occurred during Segment identify`, maybeError);
|
|
165
165
|
}
|
|
@@ -196,7 +196,7 @@ export class TelemetryManager extends BaseManager {
|
|
|
196
196
|
this._segmentClient.group(
|
|
197
197
|
payload as Parameters<typeof this._segmentClient.group>[0],
|
|
198
198
|
(maybeError?: Error) => {
|
|
199
|
-
if (maybeError) {
|
|
199
|
+
if (maybeError && import.meta.env.DEV) {
|
|
200
200
|
// TODO: Not sure how we want to deal with that
|
|
201
201
|
console.warn(`An error occurred during Segment group`, maybeError);
|
|
202
202
|
}
|
|
@@ -94,7 +94,7 @@ type CommandInitEndSegmentEvent = SegmentEvent<
|
|
|
94
94
|
|
|
95
95
|
type ReviewSegmentEvent = SegmentEvent<
|
|
96
96
|
typeof SegmentEventType.review,
|
|
97
|
-
{
|
|
97
|
+
{ rating: number; comment: string }
|
|
98
98
|
>;
|
|
99
99
|
|
|
100
100
|
type OnboardingStartSegmentEvent = SegmentEvent<
|
|
@@ -123,18 +123,15 @@ type OnboardingContinueScreen3SegmentEvent = SegmentEvent<
|
|
|
123
123
|
>;
|
|
124
124
|
|
|
125
125
|
type SliceSimulatorSetupSegmentEvent = SegmentEvent<
|
|
126
|
-
typeof SegmentEventType.sliceSimulator_setup
|
|
127
|
-
{ framework: string }
|
|
126
|
+
typeof SegmentEventType.sliceSimulator_setup
|
|
128
127
|
>;
|
|
129
128
|
|
|
130
129
|
type SliceSimulatorOpenSegmentEvent = SegmentEvent<
|
|
131
|
-
typeof SegmentEventType.sliceSimulator_open
|
|
132
|
-
{ framework: string }
|
|
130
|
+
typeof SegmentEventType.sliceSimulator_open
|
|
133
131
|
>;
|
|
134
132
|
|
|
135
133
|
type SliceSimulatorIsNotRunningSegmentEvent = SegmentEvent<
|
|
136
|
-
typeof SegmentEventType.sliceSimulator_isNotRunning
|
|
137
|
-
{ framework: string }
|
|
134
|
+
typeof SegmentEventType.sliceSimulator_isNotRunning
|
|
138
135
|
>;
|
|
139
136
|
|
|
140
137
|
type PageViewSegmentEvent = SegmentEvent<
|
|
@@ -145,13 +142,13 @@ type PageViewSegmentEvent = SegmentEvent<
|
|
|
145
142
|
search: string;
|
|
146
143
|
title: string;
|
|
147
144
|
referrer: string;
|
|
148
|
-
|
|
145
|
+
adapter: string;
|
|
149
146
|
}
|
|
150
147
|
>;
|
|
151
148
|
|
|
152
149
|
type OpenVideoTutorialsSegmentEvent = SegmentEvent<
|
|
153
150
|
typeof SegmentEventType.openVideoTutorials,
|
|
154
|
-
{
|
|
151
|
+
{ video: string }
|
|
155
152
|
>;
|
|
156
153
|
|
|
157
154
|
type CustomTypeCreatedSegmentEvent = SegmentEvent<
|
package/src/types.ts
CHANGED
|
@@ -36,8 +36,6 @@ export type SliceMachineConfigPluginRegistration<
|
|
|
36
36
|
* Slice Machine configuration from `slicemachine.config.js`.
|
|
37
37
|
*/
|
|
38
38
|
export type SliceMachineConfig = {
|
|
39
|
-
// TODO: Is `_latest` necessary? Can we deprecate it?
|
|
40
|
-
_latest: string;
|
|
41
39
|
// TODO: Can we make `apiEndpoint` optional?
|
|
42
40
|
apiEndpoint?: string;
|
|
43
41
|
// NOTE: This is a new property.
|