@statelyai/sdk 0.14.1 → 0.15.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/README.md +50 -3
- package/dist/auth.d.mts +1 -1
- package/dist/embed.d.mts +4 -3
- package/dist/{graph-R0sbxnZ7.d.mts → graph-DuOeLGvh.d.mts} +5 -1
- package/dist/graph.d.mts +1 -1
- package/dist/graph.mjs +4 -0
- package/dist/{index-DVjNSTuQ.d.mts → index-ag6K2iAS.d.mts} +53 -5
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +4 -4
- package/dist/{inspect-BcKTFJI1.mjs → inspect-DWDTNMEc.mjs} +15 -6
- package/dist/inspect.d.mts +1 -1
- package/dist/inspect.mjs +1 -1
- package/dist/patchTypes.d.mts +1 -1
- package/dist/protocol.d.mts +8 -6
- package/dist/{dist-C8jVuuHf.mjs → statelyPragma-Bm9O4XV6.mjs} +351 -4466
- package/dist/studio-Da5pyxv6.d.mts +303 -0
- package/dist/studio-txdyJHD7.mjs +4725 -0
- package/dist/studio.d.mts +2 -125
- package/dist/studio.mjs +2 -171
- package/dist/sync.d.mts +2 -2
- package/dist/sync.mjs +221 -30
- package/package.json +4 -3
- /package/dist/{auth-DmPZiERd.d.mts → auth-2Thaw42j.d.mts} +0 -0
- /package/dist/{inspect-DQ_7I7eH.d.mts → inspect-DenVP7IE.d.mts} +0 -0
package/dist/studio.d.mts
CHANGED
|
@@ -1,125 +1,2 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
|
|
3
|
-
//#region src/studio.d.ts
|
|
4
|
-
interface StudioClientOptions {
|
|
5
|
-
baseUrl?: string;
|
|
6
|
-
credential?: StatelyCredential;
|
|
7
|
-
/** @deprecated Use credential: { type: 'api_key', token }. */
|
|
8
|
-
apiKey?: string;
|
|
9
|
-
authMode?: StatelyAuthMode;
|
|
10
|
-
fetch?: typeof fetch;
|
|
11
|
-
}
|
|
12
|
-
interface VerifyApiKeyResponse {
|
|
13
|
-
valid: boolean;
|
|
14
|
-
}
|
|
15
|
-
type ProjectVisibility = 'Public' | 'Private' | 'Unlisted';
|
|
16
|
-
type RepoType = 'GITHUB';
|
|
17
|
-
interface ConnectedRepo {
|
|
18
|
-
id?: string;
|
|
19
|
-
type?: RepoType;
|
|
20
|
-
url: string;
|
|
21
|
-
owner: string;
|
|
22
|
-
repo: string;
|
|
23
|
-
branch: string;
|
|
24
|
-
treeSha: string;
|
|
25
|
-
autoSync?: boolean;
|
|
26
|
-
pathForNewFiles?: string;
|
|
27
|
-
selectedPaths?: string[];
|
|
28
|
-
lastSyncedAt?: string;
|
|
29
|
-
}
|
|
30
|
-
interface ProjectMachine {
|
|
31
|
-
machineId: string;
|
|
32
|
-
name: string;
|
|
33
|
-
}
|
|
34
|
-
interface ProjectData {
|
|
35
|
-
projectId: string;
|
|
36
|
-
machines: ProjectMachine[];
|
|
37
|
-
id?: string;
|
|
38
|
-
name?: string;
|
|
39
|
-
description?: string | null;
|
|
40
|
-
keywords?: string[];
|
|
41
|
-
visibility?: ProjectVisibility;
|
|
42
|
-
projectVersionId?: string;
|
|
43
|
-
connectedRepo?: ConnectedRepo | null;
|
|
44
|
-
}
|
|
45
|
-
interface ExtractedMachine {
|
|
46
|
-
id?: string;
|
|
47
|
-
config: Record<string, unknown>;
|
|
48
|
-
setupConfig?: Record<string, unknown>;
|
|
49
|
-
implementations?: Record<string, unknown>;
|
|
50
|
-
_type: 'setup.createMachine' | 'createMachine';
|
|
51
|
-
}
|
|
52
|
-
interface ExtractMachinesResponse {
|
|
53
|
-
machines: ExtractedMachine[];
|
|
54
|
-
error?: string;
|
|
55
|
-
}
|
|
56
|
-
interface GetMachineOptions {
|
|
57
|
-
version?: string;
|
|
58
|
-
}
|
|
59
|
-
interface CreateProjectInput {
|
|
60
|
-
name: string;
|
|
61
|
-
visibility: ProjectVisibility;
|
|
62
|
-
description?: string;
|
|
63
|
-
keywords?: string[];
|
|
64
|
-
repo?: ConnectedRepo;
|
|
65
|
-
}
|
|
66
|
-
interface EnsureProjectInput extends CreateProjectInput {
|
|
67
|
-
matchConnectedRepo?: boolean;
|
|
68
|
-
}
|
|
69
|
-
type XStateVersion = 4 | 5;
|
|
70
|
-
type CreateMachineTemplate = 'blank' | 'starter';
|
|
71
|
-
interface CreateMachineFromDefinitionInput<TDefinition = Record<string, unknown>> {
|
|
72
|
-
projectVersionId: string;
|
|
73
|
-
definition: TDefinition;
|
|
74
|
-
xstateVersion?: XStateVersion;
|
|
75
|
-
}
|
|
76
|
-
interface CreateMachineFromTemplateInput {
|
|
77
|
-
projectVersionId: string;
|
|
78
|
-
name: string;
|
|
79
|
-
template: CreateMachineTemplate;
|
|
80
|
-
xstateVersion?: XStateVersion;
|
|
81
|
-
}
|
|
82
|
-
type CreateMachineInput<TDefinition = Record<string, unknown>> = CreateMachineFromDefinitionInput<TDefinition> | CreateMachineFromTemplateInput;
|
|
83
|
-
interface UpdateMachineInput<TDefinition = Record<string, unknown>> {
|
|
84
|
-
id: string;
|
|
85
|
-
name?: string;
|
|
86
|
-
definition?: TDefinition;
|
|
87
|
-
}
|
|
88
|
-
interface StudioMachineRecord<TDefinition = Record<string, unknown>> {
|
|
89
|
-
id: string;
|
|
90
|
-
name: string;
|
|
91
|
-
definition: TDefinition;
|
|
92
|
-
projectVersionId?: string;
|
|
93
|
-
[key: string]: unknown;
|
|
94
|
-
}
|
|
95
|
-
declare class StudioApiError extends Error {
|
|
96
|
-
readonly status: number;
|
|
97
|
-
constructor(message: string, status: number);
|
|
98
|
-
}
|
|
99
|
-
interface StudioClient {
|
|
100
|
-
auth: {
|
|
101
|
-
verify(credential?: StatelyCredential | string): Promise<VerifyApiKeyResponse>;
|
|
102
|
-
};
|
|
103
|
-
projects: {
|
|
104
|
-
list(): Promise<ProjectData[]>;
|
|
105
|
-
create(input: CreateProjectInput): Promise<ProjectData>;
|
|
106
|
-
ensure(input: EnsureProjectInput): Promise<ProjectData>;
|
|
107
|
-
get(projectId: string): Promise<ProjectData>;
|
|
108
|
-
};
|
|
109
|
-
machines: {
|
|
110
|
-
create<TMachine = Record<string, unknown>>(input: CreateMachineInput<TMachine>): Promise<StudioMachineRecord<TMachine>>;
|
|
111
|
-
createMany<TMachine = Record<string, unknown>>(input: CreateMachineInput<TMachine>): Promise<Array<StudioMachineRecord<TMachine>>>;
|
|
112
|
-
update<TMachine = Record<string, unknown>>(input: UpdateMachineInput<TMachine>): Promise<StudioMachineRecord<TMachine>>;
|
|
113
|
-
get<TMachine = Record<string, unknown>>(machineId: string, options?: GetMachineOptions): Promise<TMachine>;
|
|
114
|
-
};
|
|
115
|
-
code: {
|
|
116
|
-
extractMachines(code: string, options?: {
|
|
117
|
-
credential?: StatelyCredential | null; /** @deprecated Use credential. */
|
|
118
|
-
apiKey?: string | null;
|
|
119
|
-
authMode?: StatelyAuthMode;
|
|
120
|
-
}): Promise<ExtractMachinesResponse>;
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
declare function createStatelyClient(options?: StudioClientOptions): StudioClient;
|
|
124
|
-
//#endregion
|
|
125
|
-
export { ConnectedRepo, CreateMachineFromDefinitionInput, CreateMachineFromTemplateInput, CreateMachineInput, CreateMachineTemplate, CreateProjectInput, EnsureProjectInput, ExtractMachinesResponse, ExtractedMachine, GetMachineOptions, ProjectData, ProjectMachine, ProjectVisibility, RepoType, StudioApiError, StudioClient, StudioClientOptions, StudioMachineRecord, UpdateMachineInput, VerifyApiKeyResponse, XStateVersion, createStatelyClient };
|
|
1
|
+
import { A as Machine, C as StudioMachineRecord, D as VerifyApiKeyResponse, E as UpdateProjectInput, F as ProjectVisibility, I as VerifyResult, L as XStateVersion, M as Project, N as ProjectMachineSummary, O as createStatelyClient, P as ProjectSummary, R as ResourceErrorCode, S as StudioClientOptions, T as UpdateMachineInput, _ as ProjectMachine, a as CreateMachineTemplate, b as StudioApiErrorOptions, c as EnsureProjectInput, d as ExtractedMachine, f as GetMachineOptions, g as ProjectData, h as LegacyUpdateMachineInput, i as CreateMachineInput, j as MachineVersion, k as ExtractedMachines, l as ExtractMachinesInput, m as LegacyProjectVisibility, n as CreateMachineFromDefinitionInput, o as CreateProjectInput, p as LegacyExtractMachinesOptions, r as CreateMachineFromTemplateInput, s as DEFAULT_STATELY_BASE_URL, t as ConnectedRepo, u as ExtractMachinesResponse, v as RepoType, w as StudioRequestOptions, x as StudioClient, y as StudioApiError } from "./studio-Da5pyxv6.mjs";
|
|
2
|
+
export { ConnectedRepo, CreateMachineFromDefinitionInput, CreateMachineFromTemplateInput, CreateMachineInput, CreateMachineTemplate, CreateProjectInput, DEFAULT_STATELY_BASE_URL, EnsureProjectInput, ExtractMachinesInput, ExtractMachinesResponse, ExtractedMachine, ExtractedMachines, GetMachineOptions, LegacyExtractMachinesOptions, LegacyProjectVisibility, LegacyUpdateMachineInput, Machine, MachineVersion, Project, ProjectData, ProjectMachine, ProjectMachineSummary, ProjectSummary, ProjectVisibility, RepoType, ResourceErrorCode, StudioApiError, StudioApiErrorOptions, StudioClient, StudioClientOptions, StudioMachineRecord, StudioRequestOptions, UpdateMachineInput, UpdateProjectInput, VerifyApiKeyResponse, VerifyResult, XStateVersion, createStatelyClient };
|
package/dist/studio.mjs
CHANGED
|
@@ -1,172 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as StudioApiError, r as createStatelyClient, t as DEFAULT_STATELY_BASE_URL } from "./studio-txdyJHD7.mjs";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
var StudioApiError = class extends Error {
|
|
5
|
-
status;
|
|
6
|
-
constructor(message, status) {
|
|
7
|
-
super(message);
|
|
8
|
-
this.name = "StudioApiError";
|
|
9
|
-
this.status = status;
|
|
10
|
-
}
|
|
11
|
-
};
|
|
12
|
-
function getFetch(fetchImpl) {
|
|
13
|
-
const resolvedFetch = fetchImpl ?? globalThis.fetch;
|
|
14
|
-
if (!resolvedFetch) throw new Error("No fetch implementation available. Pass one via createStatelyClient({ fetch }).");
|
|
15
|
-
return resolvedFetch;
|
|
16
|
-
}
|
|
17
|
-
function joinApiUrl(baseUrl, path) {
|
|
18
|
-
return `${baseUrl.replace(/\/+$/, "")}/registry/api/v1${path}`;
|
|
19
|
-
}
|
|
20
|
-
async function parseJson(response) {
|
|
21
|
-
if (!response.headers.get("content-type")?.includes("application/json")) return null;
|
|
22
|
-
return response.json().catch(() => null);
|
|
23
|
-
}
|
|
24
|
-
function getErrorMessage(data, status) {
|
|
25
|
-
if (typeof data === "object" && data !== null) {
|
|
26
|
-
if ("error" in data && typeof data.error === "string") return data.error;
|
|
27
|
-
if ("error" in data) {
|
|
28
|
-
const error = data.error;
|
|
29
|
-
if (typeof error === "object" && error !== null && "json" in error) {
|
|
30
|
-
const errorJson = error.json;
|
|
31
|
-
if (typeof errorJson === "object" && errorJson !== null && "message" in errorJson && typeof errorJson.message === "string") return errorJson.message;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
if (Array.isArray(data)) for (const item of data) {
|
|
36
|
-
const message = getErrorMessage(item, status);
|
|
37
|
-
if (message !== `HTTP ${status}`) return message;
|
|
38
|
-
}
|
|
39
|
-
return `HTTP ${status}`;
|
|
40
|
-
}
|
|
41
|
-
function unwrapResponseData(data) {
|
|
42
|
-
if (typeof data === "object" && data !== null && "data" in data) return data.data;
|
|
43
|
-
return data;
|
|
44
|
-
}
|
|
45
|
-
function normalizeProjectMachine(machine) {
|
|
46
|
-
if (typeof machine !== "object" || machine === null) return null;
|
|
47
|
-
const candidate = machine;
|
|
48
|
-
const machineId = typeof candidate.machineId === "string" ? candidate.machineId : typeof candidate.id === "string" ? candidate.id : void 0;
|
|
49
|
-
if (!machineId) return null;
|
|
50
|
-
return {
|
|
51
|
-
machineId,
|
|
52
|
-
name: typeof candidate.name === "string" && candidate.name.trim().length > 0 ? candidate.name : typeof candidate.key === "string" && candidate.key.trim().length > 0 ? candidate.key : machineId
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
function normalizeProjectData(project) {
|
|
56
|
-
const machines = Array.isArray(project.machines) ? project.machines.map((machine) => normalizeProjectMachine(machine)).filter((machine) => machine != null) : [];
|
|
57
|
-
if (project.projectVersionId) return {
|
|
58
|
-
...project,
|
|
59
|
-
machines
|
|
60
|
-
};
|
|
61
|
-
if (project.projectId && project.id) return {
|
|
62
|
-
...project,
|
|
63
|
-
machines,
|
|
64
|
-
projectVersionId: project.id
|
|
65
|
-
};
|
|
66
|
-
return {
|
|
67
|
-
...project,
|
|
68
|
-
machines
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
function normalizeRepoUrl(url) {
|
|
72
|
-
if (!url) return;
|
|
73
|
-
return url.replace(/\.git$/i, "").replace(/\/+$/, "");
|
|
74
|
-
}
|
|
75
|
-
function connectedReposMatch(left, right) {
|
|
76
|
-
if (!left || !right) return false;
|
|
77
|
-
const normalizedLeft = normalizeRepoUrl(left.url);
|
|
78
|
-
const normalizedRight = normalizeRepoUrl(right.url);
|
|
79
|
-
return normalizedLeft != null && normalizedRight != null && normalizedLeft === normalizedRight && left.branch === right.branch || left.owner === right.owner && left.repo === right.repo && left.branch === right.branch;
|
|
80
|
-
}
|
|
81
|
-
function createStatelyClient(options = {}) {
|
|
82
|
-
const baseUrl = options.baseUrl ?? "https://stately.ai";
|
|
83
|
-
const fetchImpl = getFetch(options.fetch);
|
|
84
|
-
const defaultCredential = options.credential ?? (options.apiKey ? {
|
|
85
|
-
type: "api_key",
|
|
86
|
-
token: options.apiKey
|
|
87
|
-
} : void 0);
|
|
88
|
-
const defaultAuthMode = options.authMode ?? "auto";
|
|
89
|
-
async function request(path, init = {}, credentialOverride, authModeOverride) {
|
|
90
|
-
const headers = new Headers(init.headers);
|
|
91
|
-
const authMode = authModeOverride ?? defaultAuthMode;
|
|
92
|
-
const credential = credentialOverride ?? defaultCredential;
|
|
93
|
-
if (authMode !== "none") {
|
|
94
|
-
const token = getCredentialToken(credential);
|
|
95
|
-
if (authMode === "bearer" && (!token || !credential)) throw new StudioApiError("No Stately credential configured. Pass createStatelyClient({ credential }) or use authMode: \"auto\" to let the server decide whether authentication is required.", 401);
|
|
96
|
-
if (token && credential) headers.set("Authorization", createAuthorizationHeader(credential));
|
|
97
|
-
}
|
|
98
|
-
const response = await fetchImpl(joinApiUrl(baseUrl, path), {
|
|
99
|
-
...init,
|
|
100
|
-
headers
|
|
101
|
-
});
|
|
102
|
-
const data = await parseJson(response);
|
|
103
|
-
if (!response.ok) throw new StudioApiError(getErrorMessage(data, response.status), response.status);
|
|
104
|
-
return unwrapResponseData(data);
|
|
105
|
-
}
|
|
106
|
-
return {
|
|
107
|
-
auth: { verify(credential) {
|
|
108
|
-
return request("/verify", { method: "GET" }, credential);
|
|
109
|
-
} },
|
|
110
|
-
projects: {
|
|
111
|
-
list() {
|
|
112
|
-
return request("/projects", { method: "GET" }).then((projects) => projects.map(normalizeProjectData));
|
|
113
|
-
},
|
|
114
|
-
create(input) {
|
|
115
|
-
return request("/projects/create", {
|
|
116
|
-
method: "POST",
|
|
117
|
-
headers: { "Content-Type": "application/json" },
|
|
118
|
-
body: JSON.stringify(input)
|
|
119
|
-
}).then(normalizeProjectData);
|
|
120
|
-
},
|
|
121
|
-
async ensure(input) {
|
|
122
|
-
if (input.repo && input.matchConnectedRepo !== false) {
|
|
123
|
-
const existingProject = (await this.list()).find((project) => connectedReposMatch(project.connectedRepo, input.repo));
|
|
124
|
-
if (existingProject) return existingProject;
|
|
125
|
-
}
|
|
126
|
-
return this.create(input);
|
|
127
|
-
},
|
|
128
|
-
get(projectId) {
|
|
129
|
-
return request(`/projects/${encodeURIComponent(projectId)}`, { method: "GET" }).then(normalizeProjectData);
|
|
130
|
-
}
|
|
131
|
-
},
|
|
132
|
-
machines: {
|
|
133
|
-
async create(input) {
|
|
134
|
-
return request("/machines/create", {
|
|
135
|
-
method: "POST",
|
|
136
|
-
headers: { "Content-Type": "application/json" },
|
|
137
|
-
body: JSON.stringify(input)
|
|
138
|
-
});
|
|
139
|
-
},
|
|
140
|
-
async createMany(input) {
|
|
141
|
-
return [await this.create(input)];
|
|
142
|
-
},
|
|
143
|
-
update(input) {
|
|
144
|
-
return request(`/machines/${encodeURIComponent(input.id)}`, {
|
|
145
|
-
method: "PATCH",
|
|
146
|
-
headers: { "Content-Type": "application/json" },
|
|
147
|
-
body: JSON.stringify(input)
|
|
148
|
-
});
|
|
149
|
-
},
|
|
150
|
-
get(machineId, getOptions = {}) {
|
|
151
|
-
const search = new URLSearchParams();
|
|
152
|
-
if (getOptions.version) search.set("version", getOptions.version);
|
|
153
|
-
const suffix = search.size > 0 ? `?${search.toString()}` : "";
|
|
154
|
-
return request(`/machines/${encodeURIComponent(machineId)}${suffix}`, { method: "GET" });
|
|
155
|
-
}
|
|
156
|
-
},
|
|
157
|
-
code: { extractMachines(code, extractOptions = {}) {
|
|
158
|
-
const credential = extractOptions.credential ?? (extractOptions.apiKey ? {
|
|
159
|
-
type: "api_key",
|
|
160
|
-
token: extractOptions.apiKey
|
|
161
|
-
} : void 0);
|
|
162
|
-
return request("/code", {
|
|
163
|
-
method: "POST",
|
|
164
|
-
headers: { "Content-Type": "application/json" },
|
|
165
|
-
body: JSON.stringify({ code })
|
|
166
|
-
}, credential, extractOptions.authMode);
|
|
167
|
-
} }
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
//#endregion
|
|
172
|
-
export { StudioApiError, createStatelyClient };
|
|
3
|
+
export { DEFAULT_STATELY_BASE_URL, StudioApiError, createStatelyClient };
|
package/dist/sync.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { b as DigraphConfig, i as StatelyGraph } from "./graph-
|
|
2
|
-
import {
|
|
1
|
+
import { b as DigraphConfig, i as StatelyGraph } from "./graph-DuOeLGvh.mjs";
|
|
2
|
+
import { C as StudioMachineRecord, L as XStateVersion, g as ProjectData, o as CreateProjectInput, x as StudioClient } from "./studio-Da5pyxv6.mjs";
|
|
3
3
|
import { GraphDiff } from "@statelyai/graph";
|
|
4
4
|
|
|
5
5
|
//#region src/sync.d.ts
|
package/dist/sync.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createStatelyClient } from "./studio.mjs";
|
|
2
|
-
import {
|
|
1
|
+
import { r as createStatelyClient } from "./studio-txdyJHD7.mjs";
|
|
2
|
+
import { i as INLINE_EXPRESSION_DIRECTIVE_FIELDS, m as xstateSourceToConfig, n as getStatelyPragma, p as serializeJS, r as upsertStatelyPragma, s as detectXStateSourceProfile, t as findStatelyPragmaAttachments, u as graphToXStateTS } from "./statelyPragma-Bm9O4XV6.mjs";
|
|
3
3
|
import { fromStudioMachine, toStudioMachine } from "./graph.mjs";
|
|
4
4
|
import * as ts$1 from "typescript";
|
|
5
5
|
import ts from "typescript";
|
|
@@ -65,9 +65,35 @@ function createFileSourceDocumentResolver() {
|
|
|
65
65
|
resolveImport(fromDocument, specifier) {
|
|
66
66
|
const importedFileName = resolveImportPath(fromDocument.fileName, specifier);
|
|
67
67
|
return importedFileName ? readFileSnapshot(importedFileName) : null;
|
|
68
|
+
},
|
|
69
|
+
resolvePackageJson(fromDocument, packageName) {
|
|
70
|
+
let directory = path$1.dirname(path$1.resolve(fromDocument.fileName));
|
|
71
|
+
while (true) {
|
|
72
|
+
const packageJson = readFileSnapshot(path$1.join(directory, "package.json"));
|
|
73
|
+
if (packageJson && packageJsonDeclares(packageJson.text, packageName)) return packageJson;
|
|
74
|
+
const parent = path$1.dirname(directory);
|
|
75
|
+
if (parent === directory) return null;
|
|
76
|
+
directory = parent;
|
|
77
|
+
}
|
|
68
78
|
}
|
|
69
79
|
};
|
|
70
80
|
}
|
|
81
|
+
function packageJsonDeclares(text, packageName) {
|
|
82
|
+
try {
|
|
83
|
+
const manifest = JSON.parse(text);
|
|
84
|
+
return [
|
|
85
|
+
"dependencies",
|
|
86
|
+
"devDependencies",
|
|
87
|
+
"peerDependencies",
|
|
88
|
+
"optionalDependencies"
|
|
89
|
+
].some((field) => {
|
|
90
|
+
const dependencies = manifest[field];
|
|
91
|
+
return Boolean(dependencies && typeof dependencies === "object" && Object.prototype.hasOwnProperty.call(dependencies, packageName));
|
|
92
|
+
});
|
|
93
|
+
} catch {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
71
97
|
function resolveImportPath(fromFileName, specifier) {
|
|
72
98
|
if (!specifier.startsWith(".")) return null;
|
|
73
99
|
const basePath = path$1.resolve(path$1.dirname(fromFileName), specifier);
|
|
@@ -121,20 +147,116 @@ function collectXStateSourceLocations(sourceText, document, options = {}) {
|
|
|
121
147
|
const states = [];
|
|
122
148
|
const statesObjectLocations = [];
|
|
123
149
|
collectStateLocations(root, [], states, statesObjectLocations, bindings, staticValues, root);
|
|
150
|
+
const packageProfile = detectXStatePackageProfile(options.resolver?.resolvePackageJson?.({
|
|
151
|
+
fileName: document.fileName,
|
|
152
|
+
uri
|
|
153
|
+
}, "xstate"));
|
|
124
154
|
const rootProfile = detectXStateSourceProfile(sourceText);
|
|
125
155
|
const referencedStateSymbols = new Set([...states, ...statesObjectLocations].map((state) => state.symbol).filter((symbol) => typeof symbol === "string"));
|
|
156
|
+
const resolvedTransitionFunctions = collectResolvedTransitionFunctions(root, bindings);
|
|
157
|
+
const inferredProfile = rootProfile === "xstate-v6-alpha" || resolvedTransitionFunctions.size > 0 || [...referencedStateSymbols].some((symbol) => detectXStateSourceProfile(bindings.get(symbol)?.sourceFile.text ?? "") === "xstate-v6-alpha") ? "xstate-v6-alpha" : rootProfile;
|
|
126
158
|
return {
|
|
127
159
|
version: 1,
|
|
128
|
-
profile:
|
|
160
|
+
profile: packageProfile ?? inferredProfile,
|
|
129
161
|
root: {
|
|
130
162
|
uri,
|
|
131
163
|
range: toSourceRange$1(sourceFile, root)
|
|
132
164
|
},
|
|
133
165
|
statesObject: statesObjectLocations[0],
|
|
134
166
|
states,
|
|
135
|
-
staticValues: collectStaticValueReferences(sourceFile, uri, root, staticValues)
|
|
167
|
+
staticValues: collectStaticValueReferences(sourceFile, uri, root, staticValues),
|
|
168
|
+
transitionFunctions: [...resolvedTransitionFunctions].flatMap(([symbol, resolved]) => resolved.binding.uri === uri ? [] : [{
|
|
169
|
+
symbol,
|
|
170
|
+
uri: resolved.binding.uri,
|
|
171
|
+
range: toSourceRange$1(resolved.binding.sourceFile, resolved.binding.node),
|
|
172
|
+
sourcePaths: resolved.sourcePaths
|
|
173
|
+
}])
|
|
136
174
|
};
|
|
137
175
|
}
|
|
176
|
+
function detectXStatePackageProfile(packageJson) {
|
|
177
|
+
if (!packageJson) return void 0;
|
|
178
|
+
let manifest;
|
|
179
|
+
try {
|
|
180
|
+
manifest = JSON.parse(packageJson.text);
|
|
181
|
+
} catch {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const dependencyFields = [
|
|
185
|
+
"dependencies",
|
|
186
|
+
"devDependencies",
|
|
187
|
+
"peerDependencies",
|
|
188
|
+
"optionalDependencies"
|
|
189
|
+
];
|
|
190
|
+
let range;
|
|
191
|
+
for (const field of dependencyFields) {
|
|
192
|
+
const dependencies = manifest[field];
|
|
193
|
+
if (!dependencies || typeof dependencies !== "object") continue;
|
|
194
|
+
const value = dependencies.xstate;
|
|
195
|
+
if (typeof value === "string") {
|
|
196
|
+
range = value;
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (!range) return void 0;
|
|
201
|
+
const clauseProfiles = range.replace(/^(?:workspace:|npm:xstate@)/, "").split("||").map((clause) => detectXStateRangeClauseProfile(clause.trim()));
|
|
202
|
+
const profiles = new Set(clauseProfiles);
|
|
203
|
+
if (profiles.size !== 1 || profiles.has(void 0)) return void 0;
|
|
204
|
+
return clauseProfiles[0];
|
|
205
|
+
}
|
|
206
|
+
function detectXStateRangeClauseProfile(clause) {
|
|
207
|
+
const normalizedClause = clause.replace(/([<>]=?)\s+/g, "$1");
|
|
208
|
+
let lowerRequiresV6 = false;
|
|
209
|
+
let upperRequiresV5 = false;
|
|
210
|
+
let directProfile;
|
|
211
|
+
for (const match of normalizedClause.matchAll(/(?:^|\s)([<>]=?|[~^])?v?(\d+)(?:\.(\d+|x|\*))?(?:\.(\d+|x|\*))?(?:-[0-9A-Za-z.-]+)?(?=\s|$)/g)) {
|
|
212
|
+
const operator = match[1] ?? "";
|
|
213
|
+
const major = Number(match[2]);
|
|
214
|
+
const minor = parseRangePart(match[3]);
|
|
215
|
+
const patch = parseRangePart(match[4]);
|
|
216
|
+
if (operator === ">" || operator === ">=") {
|
|
217
|
+
if (major >= 6) lowerRequiresV6 = true;
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
if (operator === "<") {
|
|
221
|
+
if (major < 6 || major === 6 && (minor ?? 0) === 0 && (patch ?? 0) === 0) upperRequiresV5 = true;
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
if (operator === "<=") {
|
|
225
|
+
if (major < 6) upperRequiresV5 = true;
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
const profile = major >= 6 ? "xstate-v6-alpha" : "xstate-v5";
|
|
229
|
+
if (directProfile && directProfile !== profile) return void 0;
|
|
230
|
+
directProfile = profile;
|
|
231
|
+
}
|
|
232
|
+
if (lowerRequiresV6 && upperRequiresV5) return void 0;
|
|
233
|
+
if (lowerRequiresV6) return "xstate-v6-alpha";
|
|
234
|
+
if (upperRequiresV5) return "xstate-v5";
|
|
235
|
+
return directProfile;
|
|
236
|
+
}
|
|
237
|
+
function parseRangePart(value) {
|
|
238
|
+
return value && /^\d+$/.test(value) ? Number(value) : void 0;
|
|
239
|
+
}
|
|
240
|
+
function collectImportedXStateTransitionSources(sourceText, document, options = {}) {
|
|
241
|
+
if (!options.resolver) return [];
|
|
242
|
+
const sourceFile = ts$1.createSourceFile(document.fileName, sourceText, ts$1.ScriptTarget.Latest, true, getScriptKind$2(document.fileName));
|
|
243
|
+
const uri = document.uri?.toString() ?? document.fileName;
|
|
244
|
+
sourceFileUris.set(sourceFile, uri);
|
|
245
|
+
const bindings = collectBindings(sourceFile, uri, document.fileName, options);
|
|
246
|
+
const root = findMachineConfigObjectLiteral(sourceFile, bindings);
|
|
247
|
+
if (!root) return [];
|
|
248
|
+
return [...collectResolvedTransitionFunctions(root, bindings)].flatMap(([localName, resolved]) => {
|
|
249
|
+
const { binding } = resolved;
|
|
250
|
+
if (binding.uri === uri) return [];
|
|
251
|
+
if (ts$1.isFunctionDeclaration(binding.node)) {
|
|
252
|
+
const name = binding.node.name;
|
|
253
|
+
if (!name) return [];
|
|
254
|
+
const suffix = binding.node.getText(binding.sourceFile).slice(name.getEnd() - binding.node.getStart(binding.sourceFile));
|
|
255
|
+
return [`${binding.node.modifiers?.some((modifier) => modifier.kind === ts$1.SyntaxKind.AsyncKeyword) ? "async " : ""}function ${localName}${suffix}`];
|
|
256
|
+
}
|
|
257
|
+
return [`const ${localName} = ${binding.node.getText(binding.sourceFile)};`];
|
|
258
|
+
});
|
|
259
|
+
}
|
|
138
260
|
function collectStaticValueBindings(sourceFile) {
|
|
139
261
|
const bindings = /* @__PURE__ */ new Map();
|
|
140
262
|
for (const statement of sourceFile.statements) {
|
|
@@ -180,9 +302,30 @@ function collectBindings(sourceFile, uri, fileName, options, cache = /* @__PURE_
|
|
|
180
302
|
function collectTopLevelBindings(sourceFile, uri) {
|
|
181
303
|
const bindings = /* @__PURE__ */ new Map();
|
|
182
304
|
for (const statement of sourceFile.statements) {
|
|
305
|
+
if (ts$1.isFunctionDeclaration(statement) && statement.name) {
|
|
306
|
+
bindings.set(statement.name.text, {
|
|
307
|
+
kind: "transitionFunction",
|
|
308
|
+
node: statement,
|
|
309
|
+
sourceFile,
|
|
310
|
+
uri,
|
|
311
|
+
bindings
|
|
312
|
+
});
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
183
315
|
if (!ts$1.isVariableStatement(statement)) continue;
|
|
184
316
|
for (const declaration of statement.declarationList.declarations) {
|
|
185
317
|
if (!ts$1.isIdentifier(declaration.name) || !declaration.initializer) continue;
|
|
318
|
+
const initializer = unwrapExpression$1(declaration.initializer);
|
|
319
|
+
if (ts$1.isArrowFunction(initializer) || ts$1.isFunctionExpression(initializer)) {
|
|
320
|
+
bindings.set(declaration.name.text, {
|
|
321
|
+
kind: "transitionFunction",
|
|
322
|
+
node: initializer,
|
|
323
|
+
sourceFile,
|
|
324
|
+
uri,
|
|
325
|
+
bindings
|
|
326
|
+
});
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
186
329
|
const objectLiteral = unwrapObjectLiteralExpression(declaration.initializer);
|
|
187
330
|
if (objectLiteral) {
|
|
188
331
|
bindings.set(declaration.name.text, {
|
|
@@ -228,6 +371,62 @@ function addImportedBindings(bindings, sourceFile, uri, fileName, options, cache
|
|
|
228
371
|
}
|
|
229
372
|
}
|
|
230
373
|
}
|
|
374
|
+
function collectResolvedTransitionFunctions(root, bindings) {
|
|
375
|
+
const found = /* @__PURE__ */ new Map();
|
|
376
|
+
const visitExpression = (expression, sourcePath) => {
|
|
377
|
+
const current = unwrapExpression$1(expression);
|
|
378
|
+
if (ts$1.isIdentifier(current)) {
|
|
379
|
+
const binding = bindings.get(current.text);
|
|
380
|
+
if (binding?.kind === "transitionFunction") {
|
|
381
|
+
const resolved = found.get(current.text) ?? {
|
|
382
|
+
binding,
|
|
383
|
+
sourcePaths: []
|
|
384
|
+
};
|
|
385
|
+
if (!resolved.sourcePaths.some((existing) => existing.length === sourcePath.length && existing.every((segment, index) => segment === sourcePath[index]))) resolved.sourcePaths.push(sourcePath);
|
|
386
|
+
found.set(current.text, resolved);
|
|
387
|
+
}
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
if (ts$1.isObjectLiteralExpression(current)) {
|
|
391
|
+
for (const property of current.properties) if (ts$1.isPropertyAssignment(property)) visitExpression(property.initializer, sourcePath);
|
|
392
|
+
else if (ts$1.isShorthandPropertyAssignment(property)) visitExpression(property.name, sourcePath);
|
|
393
|
+
else if (ts$1.isSpreadAssignment(property)) visitExpression(property.expression, sourcePath);
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
if (ts$1.isArrayLiteralExpression(current)) {
|
|
397
|
+
for (const element of current.elements) if (ts$1.isExpression(element)) visitExpression(element, sourcePath);
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
ts$1.forEachChild(current, (child) => {
|
|
401
|
+
if (ts$1.isExpression(child)) visitExpression(child, sourcePath);
|
|
402
|
+
});
|
|
403
|
+
};
|
|
404
|
+
const visitState = (state, sourcePath) => {
|
|
405
|
+
for (const propertyName of [
|
|
406
|
+
"on",
|
|
407
|
+
"after",
|
|
408
|
+
"always",
|
|
409
|
+
"onDone",
|
|
410
|
+
"onError",
|
|
411
|
+
"onSnapshot",
|
|
412
|
+
"onTimeout"
|
|
413
|
+
]) {
|
|
414
|
+
const property = state.properties.find((candidate) => ts$1.isPropertyAssignment(candidate) && getPropertyNameText$1(candidate.name) === propertyName);
|
|
415
|
+
if (property) visitExpression(property.initializer, sourcePath);
|
|
416
|
+
}
|
|
417
|
+
const states = state.properties.find((candidate) => ts$1.isPropertyAssignment(candidate) && getPropertyNameText$1(candidate.name) === "states");
|
|
418
|
+
const statesObject = states && unwrapObjectLiteralExpression(states.initializer);
|
|
419
|
+
if (!statesObject) return;
|
|
420
|
+
for (const property of statesObject.properties) {
|
|
421
|
+
if (!ts$1.isPropertyAssignment(property)) continue;
|
|
422
|
+
const child = unwrapObjectLiteralExpression(property.initializer);
|
|
423
|
+
const key = getPropertyNameText$1(property.name);
|
|
424
|
+
if (child && key) visitState(child, [...sourcePath, key]);
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
visitState(root, []);
|
|
428
|
+
return found;
|
|
429
|
+
}
|
|
231
430
|
function findMachineConfigObjectLiteral(sourceFile, bindings) {
|
|
232
431
|
let found = null;
|
|
233
432
|
const visit = (node) => {
|
|
@@ -276,7 +475,7 @@ function collectStateLocations(stateObject, parentPath, locations, statesObjectL
|
|
|
276
475
|
function resolveStateProperty(property, bindings, staticValues, root) {
|
|
277
476
|
if (ts$1.isShorthandPropertyAssignment(property)) {
|
|
278
477
|
const binding = bindings.get(property.name.text);
|
|
279
|
-
if (!binding) return null;
|
|
478
|
+
if (!binding || binding.kind === "transitionFunction") return null;
|
|
280
479
|
return {
|
|
281
480
|
key: property.name.text,
|
|
282
481
|
kind: binding.kind,
|
|
@@ -306,7 +505,7 @@ function resolveStateProperty(property, bindings, staticValues, root) {
|
|
|
306
505
|
};
|
|
307
506
|
if (ts$1.isIdentifier(property.initializer)) {
|
|
308
507
|
const binding = bindings.get(property.initializer.text);
|
|
309
|
-
if (!binding) return null;
|
|
508
|
+
if (!binding || binding.kind === "transitionFunction") return null;
|
|
310
509
|
return {
|
|
311
510
|
key: resolvedKey.key,
|
|
312
511
|
kind: binding.kind,
|
|
@@ -584,10 +783,13 @@ function parseSourceToMachine(text, document, options = {}) {
|
|
|
584
783
|
...statesObjectReplacements,
|
|
585
784
|
...importReplacements
|
|
586
785
|
].filter(removeOverlappingRanges).sort(compareSourceRangesDescending));
|
|
587
|
-
if (sourceLocations.profile === "xstate-v6-alpha")
|
|
786
|
+
if (sourceLocations.profile === "xstate-v6-alpha") {
|
|
787
|
+
const importedTransitionSources = collectImportedXStateTransitionSources(text, document, options);
|
|
788
|
+
return `import { createMachine } from "xstate";
|
|
588
789
|
|
|
589
|
-
export const machine = createMachine(${serializeJS(xstateSourceToConfig(hydratedText, { profile: "xstate-v6-alpha" }), 0)});
|
|
790
|
+
export const machine = createMachine(${serializeJS(xstateSourceToConfig(importedTransitionSources.length ? `${hydratedText}\n${importedTransitionSources.join("\n")}` : hydratedText, { profile: "xstate-v6-alpha" }), 0)});
|
|
590
791
|
`;
|
|
792
|
+
}
|
|
591
793
|
return hydratedText;
|
|
592
794
|
}
|
|
593
795
|
function readHydratedStatesObject(uri, range, states, resolver) {
|
|
@@ -1254,16 +1456,16 @@ function inferXStateTargetLanguage(targetPath) {
|
|
|
1254
1456
|
return /\.(?:c|m)?jsx?$/i.test(targetPath) ? "javascript" : "typescript";
|
|
1255
1457
|
}
|
|
1256
1458
|
async function resolveRemoteMachine(machineId, baseUrl, kind, locator, options) {
|
|
1257
|
-
const
|
|
1459
|
+
const digraph = (await (options.client ?? createStatelyClient({
|
|
1258
1460
|
apiKey: options.apiKey,
|
|
1259
1461
|
baseUrl,
|
|
1260
1462
|
fetch: options.fetch
|
|
1261
|
-
})).machines.get(machineId);
|
|
1463
|
+
})).machines.get(machineId)).definition;
|
|
1262
1464
|
return {
|
|
1263
1465
|
kind,
|
|
1264
1466
|
locator,
|
|
1265
1467
|
format: "digraph",
|
|
1266
|
-
graph: fromStudioMachine(
|
|
1468
|
+
graph: fromStudioMachine(digraph),
|
|
1267
1469
|
remoteMachineId: machineId
|
|
1268
1470
|
};
|
|
1269
1471
|
}
|
|
@@ -1332,33 +1534,22 @@ function inferDefaultProjectName(sourcePath, repo) {
|
|
|
1332
1534
|
return path.basename(sourcePath, path.extname(sourcePath));
|
|
1333
1535
|
}
|
|
1334
1536
|
async function resolvePushProject(client, sourcePath, options) {
|
|
1335
|
-
async function withResolvedProjectVersionId(project, explicitProjectVersionId) {
|
|
1336
|
-
if (project.projectVersionId) return project;
|
|
1337
|
-
if (explicitProjectVersionId) return {
|
|
1338
|
-
...project,
|
|
1339
|
-
projectVersionId: explicitProjectVersionId
|
|
1340
|
-
};
|
|
1341
|
-
const matchedProject = (await client.projects.list()).find((candidate) => {
|
|
1342
|
-
return candidate.projectId === project.projectId || candidate.id != null && project.id != null && candidate.id === project.id;
|
|
1343
|
-
});
|
|
1344
|
-
if (matchedProject?.projectVersionId) return {
|
|
1345
|
-
...project,
|
|
1346
|
-
projectVersionId: matchedProject.projectVersionId
|
|
1347
|
-
};
|
|
1348
|
-
return project;
|
|
1349
|
-
}
|
|
1350
1537
|
const explicitProject = options.project;
|
|
1351
|
-
if (explicitProject?.
|
|
1352
|
-
if (explicitProject?.
|
|
1538
|
+
if (explicitProject?.projectId) return client.projects.get(explicitProject.projectId);
|
|
1539
|
+
if (explicitProject?.projectVersionId) {
|
|
1540
|
+
const matchedProject = (await client.projects.list()).find((candidate) => candidate.projectVersionId === explicitProject.projectVersionId);
|
|
1541
|
+
if (!matchedProject) throw new Error(`No project found for projectVersionId "${explicitProject.projectVersionId}".`);
|
|
1542
|
+
return client.projects.get(matchedProject.projectId);
|
|
1543
|
+
}
|
|
1353
1544
|
const inferredRepo = explicitProject?.repo ?? await inferConnectedRepo(sourcePath, options.cwd);
|
|
1354
1545
|
const projectInput = {
|
|
1355
1546
|
name: explicitProject?.name ?? inferDefaultProjectName(sourcePath, inferredRepo),
|
|
1356
|
-
visibility: explicitProject?.visibility ?? "
|
|
1547
|
+
visibility: explicitProject?.visibility ?? "private",
|
|
1357
1548
|
...explicitProject?.description ? { description: explicitProject.description } : {},
|
|
1358
1549
|
...explicitProject?.keywords ? { keywords: explicitProject.keywords } : {},
|
|
1359
1550
|
...inferredRepo ? { repo: inferredRepo } : {}
|
|
1360
1551
|
};
|
|
1361
|
-
return
|
|
1552
|
+
return client.projects.ensure(projectInput);
|
|
1362
1553
|
}
|
|
1363
1554
|
async function pushSync(options) {
|
|
1364
1555
|
const client = options.client ?? createStatelyClient({
|