Showing the changes to examples (1 of 13 files). Show all
Unified · Split
| @@ -14,10 +14,10 @@ import { · 13 unmodified lines | |||
| 14 | import { | 14 | import { |
| 15 | createExecutorBackend, | 15 | createExecutorBackend, |
| 16 | type ExecutorBackend, | 16 | type ExecutorBackend, |
| 17 | type ExecutorBackendServices, | 17 | type ExecutorBackendRepositories, |
| 18 | type ExecutorScopeConfigBackend, | 18 | type ExecutorWorkspaceConfigRepository, |
| 19 | type ExecutorScopeStateBackend, | 19 | type ExecutorWorkspaceStateRepository, |
| 20 | type ExecutorSourceArtifactBackend, | 20 | type ExecutorWorkspaceSourceArtifactRepository, |
| 21 | } from "@executor/platform-sdk"; | 21 | } from "@executor/platform-sdk"; |
| 22 | import type { | 22 | import type { |
| 23 | AuthArtifact, | 23 | AuthArtifact, |
| @@ -53,10 +53,13 @@ export type CreateSqliteExecutorBackendOptions = { · 29 unmodified lines | |||
| 53 | actorScopeId?: string; | 53 | actorScopeId?: string; |
| 54 | }; | 54 | }; |
| 55 | 55 | ||
| 56 | type ScopeConfig = Awaited<ReturnType<ExecutorScopeConfigBackend["load"]>>; | 56 | type ScopeConfig = Awaited<ReturnType<ExecutorWorkspaceConfigRepository["load"]>>; |
| 57 | type ScopeState = Awaited<ReturnType<ExecutorScopeStateBackend["load"]>>; | 57 | type ScopeState = Awaited<ReturnType<ExecutorWorkspaceStateRepository["load"]>>; |
| 58 | type SourceArtifact = ReturnType<ExecutorSourceArtifactBackend["build"]>; | 58 | type SourceArtifact = |
| 59 | type SourceArtifactBuildInput = Parameters<ExecutorSourceArtifactBackend["build"]>[0]; | 59 | ReturnType<ExecutorWorkspaceSourceArtifactRepository["build"]>; |
| 60 | type SourceArtifactBuildInput = Parameters< | ||
| 61 | ExecutorWorkspaceSourceArtifactRepository["build"] | ||
| 62 | >[0]; | ||
| 60 | 63 | ||
| 61 | type SecretMaterialSummary = { | 64 | type SecretMaterialSummary = { |
| 62 | id: string; | 65 | id: string; |
| @@ -924,7 +927,7 @@ export const createSqliteExecutorBackend = ( · 861 unmodified lines | |||
| 924 | : (options.databasePath ?? ":memory:"); | 927 | : (options.databasePath ?? ":memory:"); |
| 925 | 928 | ||
| 926 | return createExecutorBackend({ | 929 | return createExecutorBackend({ |
| 927 | loadServices: () => { | 930 | loadRepositories: () => { |
| 928 | const store = openSqliteStore(databasePath); | 931 | const store = openSqliteStore(databasePath); |
| 929 | const { auth, secrets, executions } = createStorageDomains(store); | 932 | const { auth, secrets, executions } = createStorageDomains(store); |
| 930 | 933 | ||
| @@ -937,9 +940,21 @@ export const createSqliteExecutorBackend = ( · 6 unmodified lines | |||
| 937 | databasePath, | 940 | databasePath, |
| 938 | }, | 941 | }, |
| 939 | }, | 942 | }, |
| 940 | storage: { | 943 | installation: { |
| 941 | installation: { | 944 | load: () => { |
| 942 | load: () => { | 945 | const row = store.db.select().from(installations).where(eq(installations.key, "active")).get(); |
| 946 | return row | ||
| 947 | ? { | ||
| 948 | scopeId: row.scopeId as LocalInstallation["scopeId"], | ||
| 949 | actorScopeId: row.actorScopeId as LocalInstallation["actorScopeId"], | ||
| 950 | resolutionScopeIds: parseJson<LocalInstallation["resolutionScopeIds"]>( | ||
| 951 | row.resolutionScopeIdsJson, | ||
| 952 | ), | ||
| 953 | } | ||
| 954 | : createInstallation(options); | ||
| 955 | }, | ||
| 956 | getOrProvision: () => { | ||
| 957 | const installation = (() => { | ||
| 943 | const row = store.db.select().from(installations).where(eq(installations.key, "active")).get(); | 958 | const row = store.db.select().from(installations).where(eq(installations.key, "active")).get(); |
| 944 | return row | 959 | return row |
| 945 | ? { | 960 | ? { |
| @@ -950,37 +965,25 @@ export const createSqliteExecutorBackend = ( · 4 unmodified lines | |||
| 950 | ), | 965 | ), |
| 951 | } | 966 | } |
| 952 | : createInstallation(options); | 967 | : createInstallation(options); |
| 953 | }, | 968 | })(); |
| 954 | getOrProvision: () => { | 969 | store.db.insert(installations).values({ |
| 955 | const installation = (() => { | 970 | key: "active", |
| 956 | const row = store.db.select().from(installations).where(eq(installations.key, "active")).get(); | 971 | scopeId: installation.scopeId, |
| 957 | return row | 972 | actorScopeId: installation.actorScopeId, |
| 958 | ? { | 973 | resolutionScopeIdsJson: JSON.stringify(installation.resolutionScopeIds), |
| 959 | scopeId: row.scopeId as LocalInstallation["scopeId"], | 974 | }).onConflictDoUpdate({ |
| 960 | actorScopeId: row.actorScopeId as LocalInstallation["actorScopeId"], | 975 | target: installations.key, |
| 961 | resolutionScopeIds: parseJson<LocalInstallation["resolutionScopeIds"]>( | 976 | set: { |
| 962 | row.resolutionScopeIdsJson, | ||
| 963 | ), | ||
| 964 | } | ||
| 965 | : createInstallation(options); | ||
| 966 | })(); | ||
| 967 | store.db.insert(installations).values({ | ||
| 968 | key: "active", | ||
| 969 | scopeId: installation.scopeId, | 977 | scopeId: installation.scopeId, |
| 970 | actorScopeId: installation.actorScopeId, | 978 | actorScopeId: installation.actorScopeId, |
| 971 | resolutionScopeIdsJson: JSON.stringify(installation.resolutionScopeIds), | 979 | resolutionScopeIdsJson: JSON.stringify(installation.resolutionScopeIds), |
| 972 | }).onConflictDoUpdate({ | 980 | }, |
| 973 | target: installations.key, | 981 | }).run(); |
| 974 | set: { | 982 | return installation; |
| 975 | scopeId: installation.scopeId, | ||
| 976 | actorScopeId: installation.actorScopeId, | ||
| 977 | resolutionScopeIdsJson: JSON.stringify(installation.resolutionScopeIds), | ||
| 978 | }, | ||
| 979 | }).run(); | ||
| 980 | return installation; | ||
| 981 | }, | ||
| 982 | }, | 983 | }, |
| 983 | scopeConfig: { | 984 | }, |
| 985 | workspace: { | ||
| 986 | config: { | ||
| 984 | load: () => { | 987 | load: () => { |
| 985 | const row = store.db.select().from(scopeConfigs).where(eq(scopeConfigs.key, "project")).get(); | 988 | const row = store.db.select().from(scopeConfigs).where(eq(scopeConfigs.key, "project")).get(); |
| 986 | const projectConfig = row | 989 | const projectConfig = row |
| @@ -1003,7 +1006,7 @@ export const createSqliteExecutorBackend = ( · 16 unmodified lines | |||
| 1003 | }, | 1006 | }, |
| 1004 | resolveRelativePath: ({ path, scopeRoot }) => resolvePath(scopeRoot, path), | 1007 | resolveRelativePath: ({ path, scopeRoot }) => resolvePath(scopeRoot, path), |
| 1005 | }, | 1008 | }, |
| 1006 | scopeState: { | 1009 | state: { |
| 1007 | load: () => { | 1010 | load: () => { |
| 1008 | const row = store.db.select().from(scopeStates).where(eq(scopeStates.key, "active")).get(); | 1011 | const row = store.db.select().from(scopeStates).where(eq(scopeStates.key, "active")).get(); |
| 1009 | return row ? parseJson<ScopeState>(row.stateJson) : defaultScopeState(); | 1012 | return row ? parseJson<ScopeState>(row.stateJson) : defaultScopeState(); |
| @@ -1039,55 +1042,52 @@ export const createSqliteExecutorBackend = ( · 29 unmodified lines | |||
| 1039 | store.db.delete(sourceArtifacts).where(eq(sourceArtifacts.sourceId, sourceId)).run(); | 1042 | store.db.delete(sourceArtifacts).where(eq(sourceArtifacts.sourceId, sourceId)).run(); |
| 1040 | }, | 1043 | }, |
| 1041 | }, | 1044 | }, |
| 1042 | auth, | 1045 | sourceAuth: auth, |
| 1043 | secrets: { | 1046 | }, |
| 1044 | ...secrets, | 1047 | secrets: { |
| 1045 | resolve: ({ ref }) => { | 1048 | ...secrets, |
| 1046 | const material = secrets.getById( | 1049 | resolve: ({ ref }) => { |
| 1047 | ref.handle as SecretMaterial["id"], | 1050 | const material = secrets.getById( |
| 1048 | ); | 1051 | ref.handle as SecretMaterial["id"], |
| 1049 | if (!material || material.value === null) { | 1052 | ); |
| 1050 | throw new Error(`Missing secret material ${ref.handle}`); | 1053 | if (!material || material.value === null) { |
| 1051 | } | 1054 | throw new Error(`Missing secret material ${ref.handle}`); |
| 1052 | return material.value; | 1055 | } |
| 1053 | }, | 1056 | return material.value; |
| 1054 | store: ({ purpose, value, name, providerId }) => { | ||
| 1055 | const now = Date.now(); | ||
| 1056 | const id = SecretMaterialIdSchema.make(`secret_${randomUUID()}`); | ||
| 1057 | const material: SecretMaterial = { | ||
| 1058 | id, | ||
| 1059 | providerId: providerId ?? SQLITE_SECRET_PROVIDER_ID, | ||
| 1060 | handle: id, | ||
| 1061 | name: name ?? null, | ||
| 1062 | purpose, | ||
| 1063 | value, | ||
| 1064 | createdAt: now, | ||
| 1065 | updatedAt: now, | ||
| 1066 | }; | ||
| 1067 | secrets.upsert(material); | ||
| 1068 | return { | ||
| 1069 | providerId: material.providerId, | ||
| 1070 | handle: material.handle, | ||
| 1071 | } satisfies SecretRef; | ||
| 1072 | }, | ||
| 1073 | delete: (ref) => | ||
| 1074 | secrets.removeById(ref.handle as SecretMaterial["id"]), | ||
| 1075 | update: ({ ref, name, value }) => { | ||
| 1076 | const updated = secrets.updateById( | ||
| 1077 | ref.handle as SecretMaterial["id"], | ||
| 1078 | { name, value }, | ||
| 1079 | ); | ||
| 1080 | if (!updated) { | ||
| 1081 | throw new Error(`Missing secret material ${ref.handle}`); | ||
| 1082 | } | ||
| 1083 | return updated; | ||
| 1084 | }, | ||
| 1085 | }, | 1057 | }, |
| 1086 | executions, | 1058 | store: ({ purpose, value, name, providerId }) => { |
| 1087 | close: async () => { | 1059 | const now = Date.now(); |
| 1088 | store.close(); | 1060 | const id = SecretMaterialIdSchema.make(`secret_${randomUUID()}`); |
| 1061 | const material: SecretMaterial = { | ||
| 1062 | id, | ||
| 1063 | providerId: providerId ?? SQLITE_SECRET_PROVIDER_ID, | ||
| 1064 | handle: id, | ||
| 1065 | name: name ?? null, | ||
| 1066 | purpose, | ||
| 1067 | value, | ||
| 1068 | createdAt: now, | ||
| 1069 | updatedAt: now, | ||
| 1070 | }; | ||
| 1071 | secrets.upsert(material); | ||
| 1072 | return { | ||
| 1073 | providerId: material.providerId, | ||
| 1074 | handle: material.handle, | ||
| 1075 | } satisfies SecretRef; | ||
| 1076 | }, | ||
| 1077 | delete: (ref) => | ||
| 1078 | secrets.removeById(ref.handle as SecretMaterial["id"]), | ||
| 1079 | update: ({ ref, name, value }) => { | ||
| 1080 | const updated = secrets.updateById( | ||
| 1081 | ref.handle as SecretMaterial["id"], | ||
| 1082 | { name, value }, | ||
| 1083 | ); | ||
| 1084 | if (!updated) { | ||
| 1085 | throw new Error(`Missing secret material ${ref.handle}`); | ||
| 1086 | } | ||
| 1087 | return updated; | ||
| 1089 | }, | 1088 | }, |
| 1090 | }, | 1089 | }, |
| 1090 | executions, | ||
| 1091 | instanceConfig: { | 1091 | instanceConfig: { |
| 1092 | resolve: () => ({ | 1092 | resolve: () => ({ |
| 1093 | platform: "sqlite-sdk-example", | 1093 | platform: "sqlite-sdk-example", |
| @@ -1101,7 +1101,10 @@ export const createSqliteExecutorBackend = ( · 7 unmodified lines | |||
| 1101 | defaultSecretStoreProvider: SQLITE_SECRET_PROVIDER_ID, | 1101 | defaultSecretStoreProvider: SQLITE_SECRET_PROVIDER_ID, |
| 1102 | }), | 1102 | }), |
| 1103 | }, | 1103 | }, |
| 1104 | } satisfies ExecutorBackendServices; | 1104 | close: async () => { |
| 1105 | store.close(); | ||
| 1106 | }, | ||
| 1107 | } satisfies ExecutorBackendRepositories; | ||
| 1105 | }, | 1108 | }, |
| 1106 | }); | 1109 | }); |
| 1107 | }; | 1110 | }; |