@superblocksteam/sdk 2.0.6-next.2 → 2.0.6-next.21
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/application-build.mjs +4 -0
- package/dist/application-build.mjs.map +1 -1
- package/dist/cli-replacement/automatic-upgrades.d.ts.map +1 -1
- package/dist/cli-replacement/automatic-upgrades.js +140 -77
- package/dist/cli-replacement/automatic-upgrades.js.map +1 -1
- package/dist/dev-utils/dev-server.d.mts.map +1 -1
- package/dist/dev-utils/dev-server.mjs +5 -1
- package/dist/dev-utils/dev-server.mjs.map +1 -1
- package/dist/dev-utils/vite-plugin-build-manifest-stub.d.mts +10 -0
- package/dist/dev-utils/vite-plugin-build-manifest-stub.d.mts.map +1 -0
- package/dist/dev-utils/vite-plugin-build-manifest-stub.mjs +27 -0
- package/dist/dev-utils/vite-plugin-build-manifest-stub.mjs.map +1 -0
- package/dist/dev-utils/vite-plugin-sb-cdn.d.mts.map +1 -1
- package/dist/dev-utils/vite-plugin-sb-cdn.mjs +13 -3
- package/dist/dev-utils/vite-plugin-sb-cdn.mjs.map +1 -1
- package/dist/vite-plugin-generate-build-manifest.d.mts +21 -0
- package/dist/vite-plugin-generate-build-manifest.d.mts.map +1 -0
- package/dist/vite-plugin-generate-build-manifest.mjs +131 -0
- package/dist/vite-plugin-generate-build-manifest.mjs.map +1 -0
- package/package.json +6 -4
- package/src/application-build.mts +5 -2
- package/src/cli-replacement/automatic-upgrades.ts +163 -97
- package/src/dev-utils/dev-server.mts +7 -1
- package/src/dev-utils/vite-plugin-build-manifest-stub.mts +30 -0
- package/src/dev-utils/vite-plugin-sb-cdn.mts +14 -3
- package/src/vite-plugin-generate-build-manifest.mts +193 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { parse } from "@babel/parser";
|
|
3
|
+
import { getClientApiId } from "@superblocksteam/library-shared";
|
|
4
|
+
import { resolveLanguageSpecificStepContentFromBlocks } from "@superblocksteam/util";
|
|
5
|
+
import { getPageName } from "@superblocksteam/vite-plugin-file-sync";
|
|
6
|
+
import {
|
|
7
|
+
extractIdentifierPathsFromApi,
|
|
8
|
+
extractApiDependencies,
|
|
9
|
+
} from "@superblocksteam/vite-plugin-file-sync/binding-extraction";
|
|
10
|
+
import {
|
|
11
|
+
getScope,
|
|
12
|
+
extractImportsFromAst,
|
|
13
|
+
} from "@superblocksteam/vite-plugin-file-sync/parsing";
|
|
14
|
+
import { yellow, red } from "colorette";
|
|
15
|
+
import fg from "fast-glob";
|
|
16
|
+
import fs from "fs-extra";
|
|
17
|
+
import { createLogger } from "vite";
|
|
18
|
+
import yaml from "yaml";
|
|
19
|
+
import { getLogger } from "./dev-utils/dev-logger.mjs";
|
|
20
|
+
import type { ParseResult } from "@babel/parser";
|
|
21
|
+
import type { File } from "@babel/types";
|
|
22
|
+
import type {
|
|
23
|
+
DeleteMeLibraryApi,
|
|
24
|
+
StaticScope,
|
|
25
|
+
} from "@superblocksteam/library-shared/types";
|
|
26
|
+
import type { Plugin } from "vite";
|
|
27
|
+
|
|
28
|
+
export const scopeFileBaseName = "scope.ts";
|
|
29
|
+
export const apiFileBaseName = "api.yaml";
|
|
30
|
+
|
|
31
|
+
type ApiDependency = {
|
|
32
|
+
apiName: string;
|
|
33
|
+
params: string[];
|
|
34
|
+
dependencies: string[];
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Vite plugin that generates a build manifest for the application.
|
|
39
|
+
*
|
|
40
|
+
* This plugin will:
|
|
41
|
+
* 1. Read all api.yaml and api.yml files in the application
|
|
42
|
+
* 2. Read all scope.ts files in the application
|
|
43
|
+
* 3. Generate a build manifest for the application
|
|
44
|
+
* 4. Write the build manifest to a file in the build output directory
|
|
45
|
+
*
|
|
46
|
+
* The build manifest is a JSON object with the following properties:
|
|
47
|
+
* - apis: a map of all apis in the application keyed by their file path
|
|
48
|
+
* - apiDependencies: an array where each item represents an api and its dependencies
|
|
49
|
+
*
|
|
50
|
+
* @param root - The root directory of the application
|
|
51
|
+
* @returns A Vite plugin that generates a build manifest for the application
|
|
52
|
+
*/
|
|
53
|
+
export function generateBuildManifestPlugin(root: string) {
|
|
54
|
+
const viteLogger = createLogger();
|
|
55
|
+
const logger = getLogger();
|
|
56
|
+
viteLogger.info = logger.info;
|
|
57
|
+
viteLogger.warn = (msg: string) => {
|
|
58
|
+
logger.warn(yellow(msg));
|
|
59
|
+
};
|
|
60
|
+
viteLogger.warnOnce = (msg: string) => {
|
|
61
|
+
logger.warn(yellow(msg));
|
|
62
|
+
};
|
|
63
|
+
viteLogger.error = (msg: string) => {
|
|
64
|
+
logger.error(red(msg));
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
viteLogger.clearScreen = () => {};
|
|
68
|
+
|
|
69
|
+
const scopesByPage: Record<string, StaticScope | null> = {};
|
|
70
|
+
const apiFiles: Record<string, DeleteMeLibraryApi> = {};
|
|
71
|
+
let buildManifest: {
|
|
72
|
+
apis: Record<string, { api: DeleteMeLibraryApi; scopeId: string }>;
|
|
73
|
+
apiDependencies: ApiDependency[];
|
|
74
|
+
} = { apis: {}, apiDependencies: [] };
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
name: "sb-generate-build-manifest",
|
|
78
|
+
apply: "build",
|
|
79
|
+
enforce: "pre",
|
|
80
|
+
|
|
81
|
+
async buildStart() {
|
|
82
|
+
const apiDocuments = await fg(["**/api.yaml", "**/api.yml"], {
|
|
83
|
+
cwd: root,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
for (const apiFilePath of apiDocuments) {
|
|
87
|
+
const absoluteApiFilePath = path.join(root, apiFilePath);
|
|
88
|
+
|
|
89
|
+
const document = await fs.readFile(absoluteApiFilePath, "utf-8");
|
|
90
|
+
const apiPb = yaml.parse(document);
|
|
91
|
+
|
|
92
|
+
await resolveLanguageSpecificStepContentFromBlocks(
|
|
93
|
+
path.dirname(absoluteApiFilePath),
|
|
94
|
+
apiPb.blocks ?? [],
|
|
95
|
+
{},
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
const pageName = getPageName(apiFilePath);
|
|
99
|
+
apiPb.metadata.id = getClientApiId(apiPb.metadata.name, pageName);
|
|
100
|
+
apiFiles[apiFilePath] = { apiPb, pageName };
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
transform(code: string, id: string) {
|
|
105
|
+
if (id.endsWith(scopeFileBaseName)) {
|
|
106
|
+
const ast = parse(code, {
|
|
107
|
+
sourceType: "module",
|
|
108
|
+
sourceFilename: id,
|
|
109
|
+
plugins: [["typescript", {}]],
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const scopeFileMeta: {
|
|
113
|
+
code: string;
|
|
114
|
+
ast: ParseResult<File>;
|
|
115
|
+
imports: Record<string, boolean>;
|
|
116
|
+
} = {
|
|
117
|
+
code,
|
|
118
|
+
ast,
|
|
119
|
+
imports: extractImportsFromAst(ast),
|
|
120
|
+
};
|
|
121
|
+
const scope = getScope(id, scopeFileMeta);
|
|
122
|
+
|
|
123
|
+
scopesByPage[getPageName(id)] = scope;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return code;
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
async generateBundle() {
|
|
130
|
+
const allApiNames = getAllUniqueApiNames(apiFiles);
|
|
131
|
+
|
|
132
|
+
const allApis = Object.entries(apiFiles).reduce(
|
|
133
|
+
(acc, [id, api]) => {
|
|
134
|
+
acc[id] = {
|
|
135
|
+
api,
|
|
136
|
+
scopeId: scopesByPage[api.pageName]?.scopeId ?? "",
|
|
137
|
+
};
|
|
138
|
+
return acc;
|
|
139
|
+
},
|
|
140
|
+
{} as Record<string, { api: DeleteMeLibraryApi; scopeId: string }>,
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
const deps = await getApiDependencies(allApiNames, apiFiles);
|
|
144
|
+
|
|
145
|
+
buildManifest = {
|
|
146
|
+
apis: allApis,
|
|
147
|
+
apiDependencies: deps,
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
this.emitFile({
|
|
151
|
+
type: "prebuilt-chunk",
|
|
152
|
+
fileName: "assets/build-manifest.js",
|
|
153
|
+
code: `export default ${JSON.stringify(buildManifest)}`,
|
|
154
|
+
exports: ["default"],
|
|
155
|
+
});
|
|
156
|
+
},
|
|
157
|
+
} as Plugin;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function getAllUniqueApiNames(
|
|
161
|
+
apiFiles: Record<string, DeleteMeLibraryApi>,
|
|
162
|
+
): string[] {
|
|
163
|
+
const allApiNamesSet = new Set<string>(
|
|
164
|
+
Object.values(apiFiles).map((api) => api.apiPb.metadata.name),
|
|
165
|
+
);
|
|
166
|
+
return Array.from(allApiNamesSet);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
async function getApiDependencies(
|
|
170
|
+
apiNames: string[],
|
|
171
|
+
apiFiles: Record<string, DeleteMeLibraryApi>,
|
|
172
|
+
): Promise<ApiDependency[]> {
|
|
173
|
+
const deps: ApiDependency[] = [];
|
|
174
|
+
|
|
175
|
+
// TODO: This logic is a copy of the extractApiParamsAndDependencies function in the
|
|
176
|
+
// fileSyncVitePlugin (https://github.com/superblocksteam/superblocks/blob/474c0b11d79a1d6988864fb20d5ec26f92931fde/packages/vite-plugin-file-sync/src/file-sync-vite-plugin.ts#L261-L280).
|
|
177
|
+
//
|
|
178
|
+
// This logic should be refactored so that it can be shared between the two plugins.
|
|
179
|
+
await Promise.all([
|
|
180
|
+
...Object.values(apiFiles).map(async (api) => {
|
|
181
|
+
const bindings = await extractIdentifierPathsFromApi(api);
|
|
182
|
+
const allIdentifiers = bindings.flatMap((binding) => binding.bindings);
|
|
183
|
+
const apiDependencies = extractApiDependencies(apiNames, bindings);
|
|
184
|
+
deps.push({
|
|
185
|
+
apiName: api.apiPb.metadata.name,
|
|
186
|
+
params: allIdentifiers,
|
|
187
|
+
dependencies: apiDependencies,
|
|
188
|
+
});
|
|
189
|
+
}),
|
|
190
|
+
]);
|
|
191
|
+
|
|
192
|
+
return deps;
|
|
193
|
+
}
|