flowdular 0.6.0 → 0.6.2
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/distribution.js +173 -153
- package/dist/index.js +769 -596
- package/package.json +2 -2
package/dist/distribution.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// src/module-artifact.ts
|
|
2
2
|
import { parse as parseYaml2 } from "yaml";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
|
-
import { lstat, readdir
|
|
5
|
-
import { join
|
|
4
|
+
import { lstat, readdir, readFile } from "node:fs/promises";
|
|
5
|
+
import { join } from "node:path";
|
|
6
6
|
|
|
7
7
|
// ../kernel/src/errors.ts
|
|
8
8
|
var RegistryError = class extends Error {
|
|
@@ -1670,7 +1670,7 @@ var EXPRESSIONS = new Map(
|
|
|
1670
1670
|
);
|
|
1671
1671
|
|
|
1672
1672
|
// ../contracts/src/index.ts
|
|
1673
|
-
var PLATFORM_API_VERSION = "0.2.
|
|
1673
|
+
var PLATFORM_API_VERSION = "0.2.4";
|
|
1674
1674
|
|
|
1675
1675
|
// ../kernel/src/module-compatibility.ts
|
|
1676
1676
|
function satisfiesModuleVersion(version, range) {
|
|
@@ -1863,8 +1863,6 @@ function createModuleRegistry(input) {
|
|
|
1863
1863
|
}
|
|
1864
1864
|
|
|
1865
1865
|
// src/validation.ts
|
|
1866
|
-
import { readdir, readFile } from "node:fs/promises";
|
|
1867
|
-
import { basename, dirname, join, relative } from "node:path";
|
|
1868
1866
|
import Ajv2020 from "ajv/dist/2020.js";
|
|
1869
1867
|
import { parse as parseYaml } from "yaml";
|
|
1870
1868
|
var ajv = new Ajv2020({ allErrors: true, strict: true });
|
|
@@ -1884,26 +1882,6 @@ var MONTH_NAMES = "jan feb mar apr may jun jul aug sep oct nov dec".split(
|
|
|
1884
1882
|
" "
|
|
1885
1883
|
);
|
|
1886
1884
|
var WEEKDAY_NAMES = "sun mon tue wed thu fri sat".split(" ");
|
|
1887
|
-
var SKIPPED_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
1888
|
-
".git",
|
|
1889
|
-
".flowdular",
|
|
1890
|
-
".vercel",
|
|
1891
|
-
"node_modules",
|
|
1892
|
-
"dist"
|
|
1893
|
-
]);
|
|
1894
|
-
async function findNamedFiles(root, name) {
|
|
1895
|
-
const matches = [];
|
|
1896
|
-
async function visit(directory) {
|
|
1897
|
-
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
|
1898
|
-
if (SKIPPED_DIRECTORIES.has(entry.name)) continue;
|
|
1899
|
-
const path = join(directory, entry.name);
|
|
1900
|
-
if (entry.isDirectory()) await visit(path);
|
|
1901
|
-
else if (entry.name === name) matches.push(path);
|
|
1902
|
-
}
|
|
1903
|
-
}
|
|
1904
|
-
await visit(root);
|
|
1905
|
-
return matches.sort();
|
|
1906
|
-
}
|
|
1907
1885
|
|
|
1908
1886
|
// src/module-artifact.ts
|
|
1909
1887
|
var MAX_ARTIFACT_BYTES = 48 * 1024 * 1024;
|
|
@@ -1948,7 +1926,7 @@ async function readModuleSource(root) {
|
|
|
1948
1926
|
const files = [];
|
|
1949
1927
|
let size = 0;
|
|
1950
1928
|
async function visit(directory, prefix) {
|
|
1951
|
-
for (const entry of await
|
|
1929
|
+
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
|
1952
1930
|
const path = prefix + entry.name;
|
|
1953
1931
|
if (!prefix && !ROOT_FILES.has(path) && !ROOTS.has(path)) continue;
|
|
1954
1932
|
distributionAssert(
|
|
@@ -1962,20 +1940,20 @@ async function readModuleSource(root) {
|
|
|
1962
1940
|
"MODULE_SOURCE_PATH",
|
|
1963
1941
|
`Unexpected module directory: ${path}`
|
|
1964
1942
|
);
|
|
1965
|
-
await visit(
|
|
1943
|
+
await visit(join(directory, entry.name), path + "/");
|
|
1966
1944
|
} else {
|
|
1967
1945
|
distributionAssert(
|
|
1968
1946
|
entry.isFile() && safeSourcePath(path),
|
|
1969
1947
|
"MODULE_SOURCE_PATH",
|
|
1970
1948
|
`Unexpected module source: ${path}`
|
|
1971
1949
|
);
|
|
1972
|
-
const stat2 = await lstat(
|
|
1950
|
+
const stat2 = await lstat(join(directory, entry.name));
|
|
1973
1951
|
distributionAssert(
|
|
1974
1952
|
size + stat2.size <= MAX_SOURCE_BYTES && files.length < MAX_FILES,
|
|
1975
1953
|
"MODULE_SOURCE_LIMIT",
|
|
1976
1954
|
"Module source is too large."
|
|
1977
1955
|
);
|
|
1978
|
-
const bytes = await
|
|
1956
|
+
const bytes = await readFile(join(directory, entry.name));
|
|
1979
1957
|
size += bytes.length;
|
|
1980
1958
|
files.push({
|
|
1981
1959
|
path,
|
|
@@ -2122,28 +2100,18 @@ async function packModule(root, review) {
|
|
|
2122
2100
|
}
|
|
2123
2101
|
|
|
2124
2102
|
// src/module-catalog.ts
|
|
2125
|
-
import { readFile as
|
|
2103
|
+
import { readFile as readFile2, stat } from "node:fs/promises";
|
|
2126
2104
|
|
|
2127
2105
|
// src/workspace.ts
|
|
2128
|
-
import {
|
|
2129
|
-
import { dirname as dirname2, isAbsolute, relative as relative2, resolve } from "node:path";
|
|
2106
|
+
import { dirname, isAbsolute, relative, resolve } from "node:path";
|
|
2130
2107
|
function resolveInside(root, candidate) {
|
|
2131
2108
|
const absolute = isAbsolute(candidate) ? resolve(candidate) : resolve(root, candidate);
|
|
2132
|
-
const pathFromRoot =
|
|
2109
|
+
const pathFromRoot = relative(root, absolute);
|
|
2133
2110
|
if (pathFromRoot.startsWith("..") || isAbsolute(pathFromRoot)) {
|
|
2134
2111
|
throw new Error(`Path escapes the workspace: ${candidate}`);
|
|
2135
2112
|
}
|
|
2136
2113
|
return absolute;
|
|
2137
2114
|
}
|
|
2138
|
-
async function resolveExistingInside(root, candidate) {
|
|
2139
|
-
const canonicalRoot = await realpath(root);
|
|
2140
|
-
const canonicalCandidate = await realpath(resolveInside(root, candidate));
|
|
2141
|
-
const pathFromRoot = relative2(canonicalRoot, canonicalCandidate);
|
|
2142
|
-
if (pathFromRoot.startsWith("..") || isAbsolute(pathFromRoot)) {
|
|
2143
|
-
throw new Error(`Path escapes the workspace through a link: ${candidate}`);
|
|
2144
|
-
}
|
|
2145
|
-
return canonicalCandidate;
|
|
2146
|
-
}
|
|
2147
2115
|
|
|
2148
2116
|
// src/module-catalog.ts
|
|
2149
2117
|
function platformAdmits(manifest) {
|
|
@@ -2161,7 +2129,7 @@ async function boundedRead(location, limit, fetcher = fetch) {
|
|
|
2161
2129
|
"MODULE_DOWNLOAD_LIMIT",
|
|
2162
2130
|
"Module metadata/artifact exceeds the size limit."
|
|
2163
2131
|
);
|
|
2164
|
-
const result = await
|
|
2132
|
+
const result = await readFile2(location);
|
|
2165
2133
|
distributionAssert(
|
|
2166
2134
|
result.length <= limit,
|
|
2167
2135
|
"MODULE_DOWNLOAD_LIMIT",
|
|
@@ -2334,120 +2302,163 @@ function resolveModuleReleases(catalog, target, installed) {
|
|
|
2334
2302
|
|
|
2335
2303
|
// src/module-install.ts
|
|
2336
2304
|
import {
|
|
2337
|
-
lstat as
|
|
2305
|
+
lstat as lstat2,
|
|
2338
2306
|
mkdir,
|
|
2339
|
-
readFile as
|
|
2340
|
-
readdir as
|
|
2307
|
+
readFile as readFile3,
|
|
2308
|
+
readdir as readdir2,
|
|
2341
2309
|
rename,
|
|
2342
2310
|
rm,
|
|
2343
2311
|
writeFile
|
|
2344
2312
|
} from "node:fs/promises";
|
|
2345
|
-
import { dirname as
|
|
2313
|
+
import { dirname as dirname3, join as join3, relative as relative3 } from "node:path";
|
|
2346
2314
|
|
|
2347
|
-
// src/
|
|
2315
|
+
// ../kernel/src/module-manifests.ts
|
|
2316
|
+
import { lstatSync, readdirSync, readFileSync, realpathSync } from "node:fs";
|
|
2348
2317
|
import { createRequire } from "node:module";
|
|
2349
|
-
import {
|
|
2350
|
-
|
|
2351
|
-
var
|
|
2352
|
-
|
|
2353
|
-
|
|
2318
|
+
import { dirname as dirname2, isAbsolute as isAbsolute2, join as join2, relative as relative2, resolve as resolve2 } from "node:path";
|
|
2319
|
+
var SDK_INDEX = "@flowdular/sdk/modules.json";
|
|
2320
|
+
var SDK_IMPORT = /^@flowdular\/sdk\/modules\/[a-z0-9-]+$/;
|
|
2321
|
+
var SDK_INDEX_LIMIT = 256;
|
|
2322
|
+
var UNRESOLVED = /* @__PURE__ */ new Set([
|
|
2323
|
+
"MODULE_NOT_FOUND",
|
|
2324
|
+
"ERR_PACKAGE_PATH_NOT_EXPORTED"
|
|
2325
|
+
]);
|
|
2326
|
+
var SKIPPED_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
2327
|
+
".git",
|
|
2328
|
+
".flowdular",
|
|
2329
|
+
".vercel",
|
|
2330
|
+
"node_modules",
|
|
2331
|
+
"dist"
|
|
2332
|
+
]);
|
|
2333
|
+
function errorCode(error) {
|
|
2334
|
+
return error.code ?? "";
|
|
2354
2335
|
}
|
|
2355
|
-
|
|
2356
|
-
const
|
|
2336
|
+
function insideRealPath(root, path, shown = path) {
|
|
2337
|
+
const canonicalRoot = realpathSync(root);
|
|
2338
|
+
const canonical = realpathSync(path);
|
|
2339
|
+
const fromRoot = relative2(canonicalRoot, canonical);
|
|
2340
|
+
if (fromRoot.startsWith("..") || isAbsolute2(fromRoot)) {
|
|
2341
|
+
throw new Error(`Path escapes the workspace through a link: ${shown}`);
|
|
2342
|
+
}
|
|
2343
|
+
return canonical;
|
|
2344
|
+
}
|
|
2345
|
+
function manifestPackage(path) {
|
|
2346
|
+
try {
|
|
2347
|
+
const manifest = JSON.parse(readFileSync(path, "utf8"));
|
|
2348
|
+
return typeof manifest.package === "string" ? manifest.package : void 0;
|
|
2349
|
+
} catch {
|
|
2350
|
+
return void 0;
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
function moduleRootDirectories(workspaceRoot, roots) {
|
|
2354
|
+
const configured = roots ?? ["modules"];
|
|
2355
|
+
if (!Array.isArray(configured) || configured.length === 0 || configured.some(
|
|
2356
|
+
(root) => typeof root !== "string" || !root || root.startsWith(".") || root.includes("\\") || root.split("/").some((part) => part === ".." || !part)
|
|
2357
|
+
)) {
|
|
2358
|
+
throw new Error(
|
|
2359
|
+
"Invalid modules.roots. Use relative workspace directories."
|
|
2360
|
+
);
|
|
2361
|
+
}
|
|
2362
|
+
return configured.map((root) => {
|
|
2363
|
+
const path = resolve2(workspaceRoot, root);
|
|
2364
|
+
if (!relative2(workspaceRoot, path)) {
|
|
2365
|
+
throw new Error("The workspace root cannot be a module root.");
|
|
2366
|
+
}
|
|
2367
|
+
return path;
|
|
2368
|
+
});
|
|
2369
|
+
}
|
|
2370
|
+
function sdkModuleManifests(workspaceRoot) {
|
|
2371
|
+
const require2 = createRequire(join2(workspaceRoot, "platform/package.json"));
|
|
2357
2372
|
let indexPath;
|
|
2358
2373
|
try {
|
|
2359
|
-
indexPath = require2.resolve(
|
|
2374
|
+
indexPath = require2.resolve(SDK_INDEX);
|
|
2360
2375
|
} catch (error) {
|
|
2361
|
-
if (
|
|
2362
|
-
error.code ?? ""
|
|
2363
|
-
))
|
|
2364
|
-
return /* @__PURE__ */ new Map();
|
|
2376
|
+
if (UNRESOLVED.has(errorCode(error))) return /* @__PURE__ */ new Map();
|
|
2365
2377
|
throw error;
|
|
2366
2378
|
}
|
|
2367
|
-
const index = JSON.parse(
|
|
2368
|
-
if (index.schemaVersion !== 1 || !Array.isArray(index.modules) || index.modules.length >
|
|
2379
|
+
const index = JSON.parse(readFileSync(indexPath, "utf8"));
|
|
2380
|
+
if (index.schemaVersion !== 1 || !Array.isArray(index.modules) || index.modules.length > SDK_INDEX_LIMIT) {
|
|
2369
2381
|
throw new Error("Invalid SDK module index.");
|
|
2382
|
+
}
|
|
2383
|
+
const sdkRoot = dirname2(indexPath);
|
|
2370
2384
|
const result = /* @__PURE__ */ new Map();
|
|
2371
2385
|
for (const entry of index.modules) {
|
|
2372
|
-
if (
|
|
2386
|
+
if (typeof entry?.import !== "string" || !SDK_IMPORT.test(entry.import)) {
|
|
2373
2387
|
throw new Error("Invalid SDK module entrypoint.");
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2388
|
+
}
|
|
2389
|
+
if (typeof entry.manifest !== "string") {
|
|
2390
|
+
throw new Error("Invalid SDK module manifest path.");
|
|
2391
|
+
}
|
|
2392
|
+
const lexical = resolve2(sdkRoot, entry.manifest);
|
|
2393
|
+
const fromRoot = relative2(sdkRoot, lexical);
|
|
2394
|
+
if (fromRoot.startsWith("..") || isAbsolute2(fromRoot)) {
|
|
2395
|
+
throw new Error(`Path escapes the workspace: ${entry.manifest}`);
|
|
2396
|
+
}
|
|
2397
|
+
const path = insideRealPath(sdkRoot, lexical, entry.manifest);
|
|
2378
2398
|
if (result.has(path)) throw new Error("Duplicate SDK module path.");
|
|
2379
2399
|
result.set(path, entry.import);
|
|
2380
2400
|
}
|
|
2381
2401
|
return result;
|
|
2382
2402
|
}
|
|
2383
|
-
|
|
2384
|
-
// src/module-files.ts
|
|
2385
|
-
import { createRequire as createRequire2 } from "node:module";
|
|
2386
|
-
import { lstat as lstat2, readFile as readFile6 } from "node:fs/promises";
|
|
2387
|
-
import { join as join4, relative as relative3 } from "node:path";
|
|
2388
|
-
function moduleRoots(workspace) {
|
|
2389
|
-
const roots = workspace.config.modules?.roots ?? ["modules"];
|
|
2390
|
-
if (!Array.isArray(roots) || !roots.length || roots.some(
|
|
2391
|
-
(root) => typeof root !== "string" || !root || root.startsWith(".") || root.includes("\\") || root.split("/").some((part) => part === ".." || !part)
|
|
2392
|
-
))
|
|
2393
|
-
throw new Error(
|
|
2394
|
-
"Invalid modules.roots. Use relative workspace directories."
|
|
2395
|
-
);
|
|
2396
|
-
return roots.map((root) => {
|
|
2397
|
-
const path = resolveInside(workspace.root, root);
|
|
2398
|
-
if (!relative3(workspace.root, path))
|
|
2399
|
-
throw new Error("The workspace root cannot be a module root.");
|
|
2400
|
-
return path;
|
|
2401
|
-
});
|
|
2402
|
-
}
|
|
2403
|
-
async function findModuleFiles(workspace) {
|
|
2403
|
+
function findModuleManifests(workspaceRoot, roots) {
|
|
2404
2404
|
const files = /* @__PURE__ */ new Set();
|
|
2405
|
-
for (const root of
|
|
2405
|
+
for (const root of moduleRootDirectories(workspaceRoot, roots)) {
|
|
2406
2406
|
try {
|
|
2407
|
-
|
|
2407
|
+
lstatSync(root);
|
|
2408
2408
|
} catch (error) {
|
|
2409
|
-
if (error
|
|
2409
|
+
if (errorCode(error) === "ENOENT") continue;
|
|
2410
2410
|
throw error;
|
|
2411
2411
|
}
|
|
2412
|
-
|
|
2413
|
-
for (const
|
|
2414
|
-
if (
|
|
2412
|
+
insideRealPath(workspaceRoot, root);
|
|
2413
|
+
for (const entry of readdirSync(root, { withFileTypes: true })) {
|
|
2414
|
+
if (!entry.isDirectory() || SKIPPED_DIRECTORIES.has(entry.name)) continue;
|
|
2415
|
+
const path = join2(root, entry.name, "module.json");
|
|
2416
|
+
try {
|
|
2417
|
+
if (!lstatSync(path).isDirectory()) files.add(path);
|
|
2418
|
+
} catch (error) {
|
|
2419
|
+
if (errorCode(error) !== "ENOENT") throw error;
|
|
2420
|
+
}
|
|
2415
2421
|
}
|
|
2416
2422
|
}
|
|
2417
2423
|
const packages = /* @__PURE__ */ new Set();
|
|
2418
|
-
for (const file of files)
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
for (const file of (
|
|
2423
|
-
const
|
|
2424
|
-
if (!packages.has(
|
|
2424
|
+
for (const file of files) {
|
|
2425
|
+
const name = manifestPackage(file);
|
|
2426
|
+
if (name) packages.add(name);
|
|
2427
|
+
}
|
|
2428
|
+
for (const file of sdkModuleManifests(workspaceRoot).keys()) {
|
|
2429
|
+
const name = manifestPackage(file);
|
|
2430
|
+
if (!name || !packages.has(name)) files.add(file);
|
|
2425
2431
|
}
|
|
2426
|
-
const platformPackage =
|
|
2432
|
+
const platformPackage = join2(workspaceRoot, "platform/package.json");
|
|
2433
|
+
let dependencies = {};
|
|
2427
2434
|
try {
|
|
2428
|
-
|
|
2429
|
-
const require2 = createRequire2(platformPackage);
|
|
2430
|
-
for (const name of Object.keys(pkg.dependencies ?? {}).sort()) {
|
|
2431
|
-
if (!name.startsWith("@flowdular/module-") || packages.has(name))
|
|
2432
|
-
continue;
|
|
2433
|
-
let file;
|
|
2434
|
-
try {
|
|
2435
|
-
file = require2.resolve(name + "/module.json");
|
|
2436
|
-
} catch (error) {
|
|
2437
|
-
if (["MODULE_NOT_FOUND", "ERR_PACKAGE_PATH_NOT_EXPORTED"].includes(
|
|
2438
|
-
error.code ?? ""
|
|
2439
|
-
))
|
|
2440
|
-
continue;
|
|
2441
|
-
throw error;
|
|
2442
|
-
}
|
|
2443
|
-
files.add(file);
|
|
2444
|
-
}
|
|
2435
|
+
dependencies = JSON.parse(readFileSync(platformPackage, "utf8")).dependencies ?? {};
|
|
2445
2436
|
} catch (error) {
|
|
2446
|
-
if (error
|
|
2437
|
+
if (errorCode(error) !== "ENOENT") throw error;
|
|
2438
|
+
}
|
|
2439
|
+
const require2 = createRequire(platformPackage);
|
|
2440
|
+
for (const name of Object.keys(dependencies).sort()) {
|
|
2441
|
+
if (!name.startsWith("@flowdular/module-") || packages.has(name)) continue;
|
|
2442
|
+
try {
|
|
2443
|
+
files.add(require2.resolve(`${name}/module.json`));
|
|
2444
|
+
} catch (error) {
|
|
2445
|
+
if (!UNRESOLVED.has(errorCode(error))) throw error;
|
|
2446
|
+
}
|
|
2447
2447
|
}
|
|
2448
2448
|
return [...files].sort();
|
|
2449
2449
|
}
|
|
2450
2450
|
|
|
2451
|
+
// src/module-files.ts
|
|
2452
|
+
function configuredRoots(workspace) {
|
|
2453
|
+
return workspace.config.modules?.roots;
|
|
2454
|
+
}
|
|
2455
|
+
function moduleRoots(workspace) {
|
|
2456
|
+
return [...moduleRootDirectories(workspace.root, configuredRoots(workspace))];
|
|
2457
|
+
}
|
|
2458
|
+
async function findModuleFiles(workspace) {
|
|
2459
|
+
return [...findModuleManifests(workspace.root, configuredRoots(workspace))];
|
|
2460
|
+
}
|
|
2461
|
+
|
|
2451
2462
|
// src/module-validate.ts
|
|
2452
2463
|
import { parse as parseYaml3 } from "yaml";
|
|
2453
2464
|
|
|
@@ -2682,7 +2693,7 @@ var SPELLINGS = new Map(
|
|
|
2682
2693
|
var LOCK = "flowdular.modules.lock.json";
|
|
2683
2694
|
async function exists(path) {
|
|
2684
2695
|
try {
|
|
2685
|
-
await
|
|
2696
|
+
await lstat2(path);
|
|
2686
2697
|
return true;
|
|
2687
2698
|
} catch (error) {
|
|
2688
2699
|
if (error.code === "ENOENT") return false;
|
|
@@ -2690,16 +2701,16 @@ async function exists(path) {
|
|
|
2690
2701
|
}
|
|
2691
2702
|
}
|
|
2692
2703
|
async function safeParents(workspace, path) {
|
|
2693
|
-
const parts =
|
|
2704
|
+
const parts = relative3(
|
|
2694
2705
|
workspace.root,
|
|
2695
2706
|
resolveInside(workspace.root, path)
|
|
2696
2707
|
).split("/");
|
|
2697
2708
|
let current = workspace.root;
|
|
2698
2709
|
for (const part of parts) {
|
|
2699
|
-
current =
|
|
2710
|
+
current = join3(current, part);
|
|
2700
2711
|
if (!await exists(current)) break;
|
|
2701
2712
|
distributionAssert(
|
|
2702
|
-
!(await
|
|
2713
|
+
!(await lstat2(current)).isSymbolicLink(),
|
|
2703
2714
|
"MODULE_DESTINATION_LINK",
|
|
2704
2715
|
"Module installation paths cannot contain links."
|
|
2705
2716
|
);
|
|
@@ -2722,7 +2733,7 @@ function validateLock(workspace, value) {
|
|
|
2722
2733
|
);
|
|
2723
2734
|
const path = resolveInside(workspace.root, entry.directory);
|
|
2724
2735
|
distributionAssert(
|
|
2725
|
-
moduleRoots(workspace).some((root) =>
|
|
2736
|
+
moduleRoots(workspace).some((root) => dirname3(path) === root) && !ids.has(entry.id) && !dirs.has(path.toLowerCase()),
|
|
2726
2737
|
"MODULE_LOCK_INVALID",
|
|
2727
2738
|
"Duplicate or invalid installed module path."
|
|
2728
2739
|
);
|
|
@@ -2739,17 +2750,17 @@ function validateLock(workspace, value) {
|
|
|
2739
2750
|
return lock;
|
|
2740
2751
|
}
|
|
2741
2752
|
async function readLock(workspace) {
|
|
2742
|
-
const path =
|
|
2753
|
+
const path = join3(workspace.root, LOCK);
|
|
2743
2754
|
await safeParents(workspace, path);
|
|
2744
2755
|
if (!await exists(path))
|
|
2745
2756
|
return { lock: { schemaVersion: 1, modules: [] }, raw: null };
|
|
2746
|
-
const raw = await
|
|
2757
|
+
const raw = await readFile3(path, "utf8");
|
|
2747
2758
|
return { lock: validateLock(workspace, JSON.parse(raw)), raw };
|
|
2748
2759
|
}
|
|
2749
2760
|
async function directoryHashes(root) {
|
|
2750
2761
|
const hashes = /* @__PURE__ */ Object.create(null);
|
|
2751
2762
|
async function visit(directory, prefix) {
|
|
2752
|
-
for (const entry of await
|
|
2763
|
+
for (const entry of await readdir2(directory, { withFileTypes: true })) {
|
|
2753
2764
|
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === ".git")
|
|
2754
2765
|
continue;
|
|
2755
2766
|
distributionAssert(
|
|
@@ -2759,14 +2770,14 @@ async function directoryHashes(root) {
|
|
|
2759
2770
|
);
|
|
2760
2771
|
const path = prefix + entry.name;
|
|
2761
2772
|
if (entry.isDirectory())
|
|
2762
|
-
await visit(
|
|
2773
|
+
await visit(join3(directory, entry.name), path + "/");
|
|
2763
2774
|
else {
|
|
2764
2775
|
distributionAssert(
|
|
2765
2776
|
entry.isFile(),
|
|
2766
2777
|
"MODULE_LOCAL_CHANGES",
|
|
2767
2778
|
"Installed module contains a special file."
|
|
2768
2779
|
);
|
|
2769
|
-
hashes[path] = hashBytes(await
|
|
2780
|
+
hashes[path] = hashBytes(await readFile3(join3(directory, entry.name)));
|
|
2770
2781
|
}
|
|
2771
2782
|
}
|
|
2772
2783
|
}
|
|
@@ -2795,8 +2806,8 @@ async function validateInstalledModules(workspace) {
|
|
|
2795
2806
|
for (const entry of lock.modules) {
|
|
2796
2807
|
await assertUnmodified(workspace, entry);
|
|
2797
2808
|
const manifest = JSON.parse(
|
|
2798
|
-
await
|
|
2799
|
-
|
|
2809
|
+
await readFile3(
|
|
2810
|
+
join3(workspace.root, entry.directory, "module.json"),
|
|
2800
2811
|
"utf8"
|
|
2801
2812
|
)
|
|
2802
2813
|
);
|
|
@@ -2809,14 +2820,23 @@ async function validateInstalledModules(workspace) {
|
|
|
2809
2820
|
return lock;
|
|
2810
2821
|
}
|
|
2811
2822
|
|
|
2823
|
+
// src/sdk.ts
|
|
2824
|
+
var SDK_VERSION = "0.6.2";
|
|
2825
|
+
function npmPackage(specifier) {
|
|
2826
|
+
return specifier.startsWith("@") ? specifier.split("/").slice(0, 2).join("/") : specifier.split("/")[0];
|
|
2827
|
+
}
|
|
2828
|
+
async function sdkModules(workspace) {
|
|
2829
|
+
return sdkModuleManifests(workspace.root);
|
|
2830
|
+
}
|
|
2831
|
+
|
|
2812
2832
|
// src/module-sync.ts
|
|
2813
2833
|
import { spawnSync } from "node:child_process";
|
|
2814
|
-
import { access
|
|
2815
|
-
import { dirname as
|
|
2834
|
+
import { access, mkdir as mkdir2, readFile as readFile4, rm as rm2, writeFile as writeFile2 } from "node:fs/promises";
|
|
2835
|
+
import { dirname as dirname4, join as join5 } from "node:path";
|
|
2816
2836
|
|
|
2817
2837
|
// src/format.ts
|
|
2818
|
-
import { createRequire as
|
|
2819
|
-
import { join as
|
|
2838
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
2839
|
+
import { join as join4 } from "node:path";
|
|
2820
2840
|
import { pathToFileURL } from "node:url";
|
|
2821
2841
|
var DEFAULT_OPTIONS = {
|
|
2822
2842
|
useTabs: true,
|
|
@@ -2825,9 +2845,9 @@ var DEFAULT_OPTIONS = {
|
|
|
2825
2845
|
};
|
|
2826
2846
|
var TSRX_PLUGIN = "@tsrx/prettier-plugin";
|
|
2827
2847
|
function resolveFrom(workspaceRoot, specifier) {
|
|
2828
|
-
for (const base of [
|
|
2848
|
+
for (const base of [join4(workspaceRoot, "package.json"), import.meta.url]) {
|
|
2829
2849
|
try {
|
|
2830
|
-
return
|
|
2850
|
+
return createRequire2(base).resolve(specifier);
|
|
2831
2851
|
} catch {
|
|
2832
2852
|
}
|
|
2833
2853
|
}
|
|
@@ -2853,7 +2873,7 @@ async function loadWorkspaceFormatter(workspaceRoot) {
|
|
|
2853
2873
|
return null;
|
|
2854
2874
|
}
|
|
2855
2875
|
const configured = await prettier.resolveConfig(
|
|
2856
|
-
|
|
2876
|
+
join4(workspaceRoot, "package.json"),
|
|
2857
2877
|
{ editorconfig: false }
|
|
2858
2878
|
);
|
|
2859
2879
|
const { plugins: _ignored, ...options } = configured ?? DEFAULT_OPTIONS;
|
|
@@ -2942,7 +2962,7 @@ async function loadManifests(workspace) {
|
|
|
2942
2962
|
const descriptors = /* @__PURE__ */ new Map();
|
|
2943
2963
|
for (const file of files) {
|
|
2944
2964
|
const manifest = JSON.parse(
|
|
2945
|
-
await
|
|
2965
|
+
await readFile4(file, "utf8")
|
|
2946
2966
|
);
|
|
2947
2967
|
if (!validators.module(manifest))
|
|
2948
2968
|
throw new Error(`Invalid module manifest: ${file}`);
|
|
@@ -3047,7 +3067,7 @@ async function takeSnapshots(paths) {
|
|
|
3047
3067
|
return Promise.all(
|
|
3048
3068
|
paths.map(async (path) => {
|
|
3049
3069
|
try {
|
|
3050
|
-
return { path, content: await
|
|
3070
|
+
return { path, content: await readFile4(path, "utf8") };
|
|
3051
3071
|
} catch (error) {
|
|
3052
3072
|
if (error.code === "ENOENT") {
|
|
3053
3073
|
return { path, content: void 0 };
|
|
@@ -3063,7 +3083,7 @@ async function restoreSnapshots(snapshots) {
|
|
|
3063
3083
|
await rm2(snapshot.path, { force: true });
|
|
3064
3084
|
continue;
|
|
3065
3085
|
}
|
|
3066
|
-
await mkdir2(
|
|
3086
|
+
await mkdir2(dirname4(snapshot.path), { recursive: true });
|
|
3067
3087
|
await writeFile2(snapshot.path, snapshot.content);
|
|
3068
3088
|
}
|
|
3069
3089
|
}
|
|
@@ -3093,7 +3113,7 @@ async function syncPlatformModules(workspace, apply, enabledOverride) {
|
|
|
3093
3113
|
content: generateClientComposition(modules, sdk, applicationPath)
|
|
3094
3114
|
}
|
|
3095
3115
|
].map(async (target) => {
|
|
3096
|
-
const absolute =
|
|
3116
|
+
const absolute = join5(workspace.root, target.path);
|
|
3097
3117
|
return {
|
|
3098
3118
|
...target,
|
|
3099
3119
|
content: formatter ? await formatter.format(absolute, target.content) : target.content
|
|
@@ -3102,15 +3122,15 @@ async function syncPlatformModules(workspace, apply, enabledOverride) {
|
|
|
3102
3122
|
);
|
|
3103
3123
|
const files = [];
|
|
3104
3124
|
for (const target of targets) {
|
|
3105
|
-
const absolute =
|
|
3125
|
+
const absolute = join5(workspace.root, target.path);
|
|
3106
3126
|
let current = "";
|
|
3107
3127
|
try {
|
|
3108
|
-
current = await
|
|
3128
|
+
current = await readFile4(absolute, "utf8");
|
|
3109
3129
|
} catch {
|
|
3110
3130
|
}
|
|
3111
3131
|
const changed = current !== target.content;
|
|
3112
3132
|
if (apply && changed) {
|
|
3113
|
-
await mkdir2(
|
|
3133
|
+
await mkdir2(dirname4(absolute), { recursive: true });
|
|
3114
3134
|
await writeFile2(absolute, target.content);
|
|
3115
3135
|
}
|
|
3116
3136
|
files.push({ path: target.path, changed });
|
|
@@ -3134,9 +3154,9 @@ async function enableModule(workspace, id, apply) {
|
|
|
3134
3154
|
const currentSet = new Set(current);
|
|
3135
3155
|
const newlyEnabled = enabled.filter((moduleId) => !currentSet.has(moduleId));
|
|
3136
3156
|
const configChanged = !equalIds(current, enabled);
|
|
3137
|
-
const platformPackagePath =
|
|
3157
|
+
const platformPackagePath = join5(workspace.root, "platform/package.json");
|
|
3138
3158
|
const platformPackage = JSON.parse(
|
|
3139
|
-
await
|
|
3159
|
+
await readFile4(platformPackagePath, "utf8")
|
|
3140
3160
|
);
|
|
3141
3161
|
const dependencies = platformPackage.dependencies ?? {};
|
|
3142
3162
|
const platformDependenciesAdded = modules.map((module) => npmPackage(module.package)).filter((packageName) => !(packageName in dependencies)).sort((left, right) => left.localeCompare(right));
|
|
@@ -3153,8 +3173,8 @@ async function enableModule(workspace, id, apply) {
|
|
|
3153
3173
|
}
|
|
3154
3174
|
const linked = async (module) => {
|
|
3155
3175
|
try {
|
|
3156
|
-
await
|
|
3157
|
-
|
|
3176
|
+
await access(
|
|
3177
|
+
join5(
|
|
3158
3178
|
workspace.root,
|
|
3159
3179
|
"platform/node_modules",
|
|
3160
3180
|
npmPackage(module.package)
|
|
@@ -3172,16 +3192,16 @@ async function enableModule(workspace, id, apply) {
|
|
|
3172
3192
|
if (apply) {
|
|
3173
3193
|
const snapshots = await takeSnapshots([
|
|
3174
3194
|
workspace.configPath,
|
|
3175
|
-
|
|
3195
|
+
join5(workspace.root, "pnpm-lock.yaml"),
|
|
3176
3196
|
platformPackagePath,
|
|
3177
3197
|
...Object.values(GENERATED_FILES).map(
|
|
3178
|
-
(path) =>
|
|
3198
|
+
(path) => join5(workspace.root, path)
|
|
3179
3199
|
)
|
|
3180
3200
|
]);
|
|
3181
3201
|
try {
|
|
3182
3202
|
if (configChanged) {
|
|
3183
3203
|
const config = JSON.parse(
|
|
3184
|
-
await
|
|
3204
|
+
await readFile4(workspace.configPath, "utf8")
|
|
3185
3205
|
);
|
|
3186
3206
|
const configModules = config.modules ?? {};
|
|
3187
3207
|
configModules.enabled = enabled;
|