@ts-cloud/core 0.7.59 → 0.7.61
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/index.d.ts +1 -0
- package/dist/index.js +109 -63
- package/dist/presets/management-dashboard.d.ts +10 -2
- package/dist/state-dir.d.ts +44 -0
- package/dist/state-dir.test.d.ts +1 -0
- package/dist/types.d.ts +15 -0
- package/dist/utils/cache.d.ts +10 -4
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1017,6 +1017,34 @@ var RealtimePresets = {
|
|
|
1017
1017
|
}
|
|
1018
1018
|
}
|
|
1019
1019
|
};
|
|
1020
|
+
// src/state-dir.ts
|
|
1021
|
+
import { isAbsolute, join, relative } from "node:path";
|
|
1022
|
+
var DEFAULT_STATE_DIR = ".ts-cloud";
|
|
1023
|
+
var STATE_DIR_ENV_VAR = "TS_CLOUD_STATE_DIR";
|
|
1024
|
+
var configuredStateDir = null;
|
|
1025
|
+
function setStateDir(dir) {
|
|
1026
|
+
const trimmed = dir?.trim();
|
|
1027
|
+
configuredStateDir = trimmed || null;
|
|
1028
|
+
}
|
|
1029
|
+
function stateDir() {
|
|
1030
|
+
const fromEnv = process.env[STATE_DIR_ENV_VAR]?.trim();
|
|
1031
|
+
return fromEnv || configuredStateDir || DEFAULT_STATE_DIR;
|
|
1032
|
+
}
|
|
1033
|
+
function statePath(...segments) {
|
|
1034
|
+
return join(stateDir(), ...segments);
|
|
1035
|
+
}
|
|
1036
|
+
function resolveStatePath(cwd, ...segments) {
|
|
1037
|
+
const dir = stateDir();
|
|
1038
|
+
return isAbsolute(dir) ? join(dir, ...segments) : join(cwd, dir, ...segments);
|
|
1039
|
+
}
|
|
1040
|
+
function isStatePath(path, root = process.cwd()) {
|
|
1041
|
+
const inside = (parent, child) => {
|
|
1042
|
+
const rel = relative(parent, child);
|
|
1043
|
+
return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
|
|
1044
|
+
};
|
|
1045
|
+
const absolute = isAbsolute(path) ? path : join(root, path);
|
|
1046
|
+
return inside(resolveStatePath(root), absolute);
|
|
1047
|
+
}
|
|
1020
1048
|
// src/deployment-mode.ts
|
|
1021
1049
|
function detectDeploymentTargets(config) {
|
|
1022
1050
|
const server = config.infrastructure?.compute != null;
|
|
@@ -1985,7 +2013,7 @@ function formatDiff(diff) {
|
|
|
1985
2013
|
}
|
|
1986
2014
|
// src/modules/storage.ts
|
|
1987
2015
|
import { existsSync, readdirSync } from "node:fs";
|
|
1988
|
-
import { join } from "node:path";
|
|
2016
|
+
import { join as join2 } from "node:path";
|
|
1989
2017
|
class Storage {
|
|
1990
2018
|
static createBucket(options) {
|
|
1991
2019
|
const {
|
|
@@ -2544,11 +2572,11 @@ class Storage {
|
|
|
2544
2572
|
static docsExist(options = {}) {
|
|
2545
2573
|
const { projectRoot = process.cwd(), docsPaths = ["docs", "documentation", "doc"] } = options;
|
|
2546
2574
|
for (const docsPath of docsPaths) {
|
|
2547
|
-
const fullPath =
|
|
2575
|
+
const fullPath = join2(projectRoot, docsPath);
|
|
2548
2576
|
if (existsSync(fullPath)) {
|
|
2549
2577
|
const distPaths = ["dist", "build", ".bunpress/dist", "_site", "out", "public"];
|
|
2550
2578
|
for (const distPath of distPaths) {
|
|
2551
|
-
const fullDistPath =
|
|
2579
|
+
const fullDistPath = join2(fullPath, distPath);
|
|
2552
2580
|
if (existsSync(fullDistPath)) {
|
|
2553
2581
|
try {
|
|
2554
2582
|
const files = readdirSync(fullDistPath);
|
|
@@ -2663,16 +2691,16 @@ class Storage {
|
|
|
2663
2691
|
const privatePath = paths.private || "private";
|
|
2664
2692
|
return {
|
|
2665
2693
|
web: {
|
|
2666
|
-
exists: existsSync(
|
|
2667
|
-
path:
|
|
2694
|
+
exists: existsSync(join2(projectRoot, webPath)),
|
|
2695
|
+
path: join2(projectRoot, webPath)
|
|
2668
2696
|
},
|
|
2669
2697
|
docs: {
|
|
2670
|
-
exists: existsSync(
|
|
2671
|
-
path:
|
|
2698
|
+
exists: existsSync(join2(projectRoot, docsPath)),
|
|
2699
|
+
path: join2(projectRoot, docsPath)
|
|
2672
2700
|
},
|
|
2673
2701
|
private: {
|
|
2674
|
-
exists: existsSync(
|
|
2675
|
-
path:
|
|
2702
|
+
exists: existsSync(join2(projectRoot, privatePath)),
|
|
2703
|
+
path: join2(projectRoot, privatePath)
|
|
2676
2704
|
}
|
|
2677
2705
|
};
|
|
2678
2706
|
}
|
|
@@ -14840,7 +14868,7 @@ class Auth {
|
|
|
14840
14868
|
// src/modules/deployment.ts
|
|
14841
14869
|
import { createHash } from "node:crypto";
|
|
14842
14870
|
import { copyFileSync, existsSync as existsSync2, readdirSync as readdirSync2, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
14843
|
-
import { basename, dirname, extname, join as
|
|
14871
|
+
import { basename, dirname, extname, join as join3 } from "node:path";
|
|
14844
14872
|
class Deployment {
|
|
14845
14873
|
static createApplication(options) {
|
|
14846
14874
|
const { slug, environment, applicationName, computePlatform } = options;
|
|
@@ -15202,7 +15230,7 @@ class AssetHasher {
|
|
|
15202
15230
|
if (dir === ".") {
|
|
15203
15231
|
return `${name}.${hash}${ext}`;
|
|
15204
15232
|
}
|
|
15205
|
-
return
|
|
15233
|
+
return join3(dir, `${name}.${hash}${ext}`);
|
|
15206
15234
|
}
|
|
15207
15235
|
static collectFiles(directory, relativeTo) {
|
|
15208
15236
|
const files = [];
|
|
@@ -15212,7 +15240,7 @@ class AssetHasher {
|
|
|
15212
15240
|
}
|
|
15213
15241
|
const entries = readdirSync2(directory, { withFileTypes: true });
|
|
15214
15242
|
for (const entry of entries) {
|
|
15215
|
-
const fullPath =
|
|
15243
|
+
const fullPath = join3(directory, entry.name);
|
|
15216
15244
|
if (entry.isDirectory()) {
|
|
15217
15245
|
files.push(...AssetHasher.collectFiles(fullPath, baseDir));
|
|
15218
15246
|
} else if (entry.isFile()) {
|
|
@@ -15242,7 +15270,7 @@ class AssetHasher {
|
|
|
15242
15270
|
assets.push(asset);
|
|
15243
15271
|
hashMap[relativePath] = hashedRelativePath;
|
|
15244
15272
|
if (outputDir) {
|
|
15245
|
-
const destPath =
|
|
15273
|
+
const destPath = join3(outputDir, hashedRelativePath);
|
|
15246
15274
|
const destDir = dirname(destPath);
|
|
15247
15275
|
if (!existsSync2(destDir)) {
|
|
15248
15276
|
const { mkdirSync } = __require("node:fs");
|
|
@@ -15260,7 +15288,7 @@ class AssetHasher {
|
|
|
15260
15288
|
hashMap
|
|
15261
15289
|
};
|
|
15262
15290
|
if (outputDir) {
|
|
15263
|
-
const manifestPath =
|
|
15291
|
+
const manifestPath = join3(outputDir, "asset-manifest.json");
|
|
15264
15292
|
writeFileSync(manifestPath, JSON.stringify(manifest, null, 2));
|
|
15265
15293
|
}
|
|
15266
15294
|
return manifest;
|
|
@@ -15355,7 +15383,7 @@ class AssetHasher {
|
|
|
15355
15383
|
cc = cacheControl.hashed || "public, max-age=31536000, immutable";
|
|
15356
15384
|
}
|
|
15357
15385
|
return {
|
|
15358
|
-
localPath:
|
|
15386
|
+
localPath: join3(sourceDir, asset.originalPath),
|
|
15359
15387
|
s3Key: keyPrefix ? `${keyPrefix}/${asset.hashedPath}` : asset.hashedPath,
|
|
15360
15388
|
contentType: asset.contentType,
|
|
15361
15389
|
cacheControl: cc,
|
|
@@ -22303,7 +22331,7 @@ function createDashboardSite(options) {
|
|
|
22303
22331
|
};
|
|
22304
22332
|
}
|
|
22305
22333
|
// src/presets/management-dashboard.ts
|
|
22306
|
-
var DASHBOARD_STATE_DIR =
|
|
22334
|
+
var DASHBOARD_STATE_DIR = DEFAULT_STATE_DIR;
|
|
22307
22335
|
var DASHBOARD_ENTRY = "./node_modules/@stacksjs/ts-cloud/dist/bin/cli.js";
|
|
22308
22336
|
function apexOf(domain) {
|
|
22309
22337
|
const parts = domain.split(".").filter(Boolean);
|
|
@@ -22492,7 +22520,7 @@ init_signature();
|
|
|
22492
22520
|
// src/aws/credentials.ts
|
|
22493
22521
|
import { existsSync as existsSync3, readFileSync as readFileSync2 } from "node:fs";
|
|
22494
22522
|
import { homedir } from "node:os";
|
|
22495
|
-
import { join as
|
|
22523
|
+
import { join as join4 } from "node:path";
|
|
22496
22524
|
function fromEnvironment() {
|
|
22497
22525
|
const accessKeyId = process.env.AWS_ACCESS_KEY_ID;
|
|
22498
22526
|
const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY;
|
|
@@ -22507,7 +22535,7 @@ function fromEnvironment() {
|
|
|
22507
22535
|
}
|
|
22508
22536
|
function fromSharedCredentials(options) {
|
|
22509
22537
|
const profile = options?.profile || process.env.AWS_PROFILE || "default";
|
|
22510
|
-
const credentialsPath = options?.credentialsFile ||
|
|
22538
|
+
const credentialsPath = options?.credentialsFile || join4(homedir(), ".aws", "credentials");
|
|
22511
22539
|
if (!existsSync3(credentialsPath)) {
|
|
22512
22540
|
return null;
|
|
22513
22541
|
}
|
|
@@ -22744,7 +22772,7 @@ function resolveRegion(profile) {
|
|
|
22744
22772
|
if (envRegion) {
|
|
22745
22773
|
return envRegion;
|
|
22746
22774
|
}
|
|
22747
|
-
const configPath =
|
|
22775
|
+
const configPath = join4(homedir(), ".aws", "config");
|
|
22748
22776
|
if (existsSync3(configPath)) {
|
|
22749
22777
|
try {
|
|
22750
22778
|
const content = readFileSync2(configPath, "utf-8");
|
|
@@ -24635,20 +24663,21 @@ function suggestQuotaIncrease(quotas) {
|
|
|
24635
24663
|
// src/utils/cache.ts
|
|
24636
24664
|
import { createHash as createHash2 } from "node:crypto";
|
|
24637
24665
|
import { existsSync as existsSync4, mkdirSync, readdirSync as readdirSync3, readFileSync as readFileSync3, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
24638
|
-
import { join as
|
|
24666
|
+
import { join as join5 } from "node:path";
|
|
24639
24667
|
class FileCache {
|
|
24640
24668
|
cacheDir;
|
|
24641
24669
|
ttl;
|
|
24642
24670
|
constructor(cacheDir, options = {}) {
|
|
24643
24671
|
this.cacheDir = cacheDir;
|
|
24644
24672
|
this.ttl = options.ttl || 24 * 60 * 60 * 1000;
|
|
24645
|
-
|
|
24646
|
-
|
|
24647
|
-
|
|
24673
|
+
}
|
|
24674
|
+
ensureCacheDir() {
|
|
24675
|
+
if (!existsSync4(this.cacheDir))
|
|
24676
|
+
mkdirSync(this.cacheDir, { recursive: true });
|
|
24648
24677
|
}
|
|
24649
24678
|
getCachePath(key) {
|
|
24650
24679
|
const hash2 = createHash2("sha256").update(key).digest("hex");
|
|
24651
|
-
return
|
|
24680
|
+
return join5(this.cacheDir, `${hash2}.json`);
|
|
24652
24681
|
}
|
|
24653
24682
|
get(key) {
|
|
24654
24683
|
const cachePath = this.getCachePath(key);
|
|
@@ -24669,6 +24698,7 @@ class FileCache {
|
|
|
24669
24698
|
}
|
|
24670
24699
|
}
|
|
24671
24700
|
set(key, value, hash2) {
|
|
24701
|
+
this.ensureCacheDir();
|
|
24672
24702
|
const cachePath = this.getCachePath(key);
|
|
24673
24703
|
const entry = {
|
|
24674
24704
|
value,
|
|
@@ -24681,16 +24711,20 @@ class FileCache {
|
|
|
24681
24711
|
return this.get(key) !== undefined;
|
|
24682
24712
|
}
|
|
24683
24713
|
clear() {
|
|
24714
|
+
if (!existsSync4(this.cacheDir))
|
|
24715
|
+
return;
|
|
24684
24716
|
const files = readdirSync3(this.cacheDir);
|
|
24685
24717
|
for (const file of files) {
|
|
24686
|
-
unlinkSync(
|
|
24718
|
+
unlinkSync(join5(this.cacheDir, file));
|
|
24687
24719
|
}
|
|
24688
24720
|
}
|
|
24689
24721
|
prune() {
|
|
24722
|
+
if (!existsSync4(this.cacheDir))
|
|
24723
|
+
return;
|
|
24690
24724
|
const files = readdirSync3(this.cacheDir);
|
|
24691
24725
|
const now = Date.now();
|
|
24692
24726
|
for (const file of files) {
|
|
24693
|
-
const filePath =
|
|
24727
|
+
const filePath = join5(this.cacheDir, file);
|
|
24694
24728
|
try {
|
|
24695
24729
|
const data = readFileSync3(filePath, "utf-8");
|
|
24696
24730
|
const entry = JSON.parse(data);
|
|
@@ -24706,7 +24740,7 @@ class FileCache {
|
|
|
24706
24740
|
|
|
24707
24741
|
class TemplateCache {
|
|
24708
24742
|
cache;
|
|
24709
|
-
constructor(cacheDir = "
|
|
24743
|
+
constructor(cacheDir = statePath("cache", "templates")) {
|
|
24710
24744
|
this.cache = new FileCache(cacheDir, {
|
|
24711
24745
|
ttl: 24 * 60 * 60 * 1000
|
|
24712
24746
|
});
|
|
@@ -24737,11 +24771,16 @@ class TemplateCache {
|
|
|
24737
24771
|
this.cache.prune();
|
|
24738
24772
|
}
|
|
24739
24773
|
}
|
|
24740
|
-
var
|
|
24774
|
+
var sharedTemplateCache = null;
|
|
24775
|
+
function templateCache() {
|
|
24776
|
+
if (!sharedTemplateCache)
|
|
24777
|
+
sharedTemplateCache = new TemplateCache;
|
|
24778
|
+
return sharedTemplateCache;
|
|
24779
|
+
}
|
|
24741
24780
|
// src/utils/hash.ts
|
|
24742
24781
|
import { createHash as createHash3 } from "node:crypto";
|
|
24743
24782
|
import { createReadStream, readdirSync as readdirSync4, statSync as statSync2 } from "node:fs";
|
|
24744
|
-
import { join as
|
|
24783
|
+
import { join as join6, relative as relative2 } from "node:path";
|
|
24745
24784
|
async function hashFile(filePath, options = {}) {
|
|
24746
24785
|
const algorithm = options.algorithm || "sha256";
|
|
24747
24786
|
const chunkSize = options.chunkSize || 64 * 1024;
|
|
@@ -24760,13 +24799,13 @@ function hashBuffer(buffer, algorithm = "sha256") {
|
|
|
24760
24799
|
return createHash3(algorithm).update(buffer).digest("hex");
|
|
24761
24800
|
}
|
|
24762
24801
|
async function hashDirectory(dirPath, options = {}) {
|
|
24763
|
-
const ignorePatterns = options.ignorePatterns || ["node_modules", ".git", "dist", "build",
|
|
24802
|
+
const ignorePatterns = options.ignorePatterns || ["node_modules", ".git", "dist", "build", stateDir()];
|
|
24764
24803
|
const files = [];
|
|
24765
24804
|
async function walk(dir) {
|
|
24766
24805
|
const entries = readdirSync4(dir, { withFileTypes: true });
|
|
24767
24806
|
for (const entry of entries) {
|
|
24768
|
-
const fullPath =
|
|
24769
|
-
const relativePath =
|
|
24807
|
+
const fullPath = join6(dir, entry.name);
|
|
24808
|
+
const relativePath = relative2(dirPath, fullPath);
|
|
24770
24809
|
if (ignorePatterns.some((pattern) => relativePath.includes(pattern))) {
|
|
24771
24810
|
continue;
|
|
24772
24811
|
}
|
|
@@ -45332,10 +45371,10 @@ import { execSync } from "node:child_process";
|
|
|
45332
45371
|
import { createHash as createHash4 } from "node:crypto";
|
|
45333
45372
|
import { cpSync, mkdtempSync, rmSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
45334
45373
|
import { tmpdir } from "node:os";
|
|
45335
|
-
import { dirname as dirname2, isAbsolute, join as
|
|
45374
|
+
import { dirname as dirname2, isAbsolute as isAbsolute2, join as join7, resolve } from "node:path";
|
|
45336
45375
|
import { fileURLToPath } from "node:url";
|
|
45337
45376
|
function adapterSourcePath() {
|
|
45338
|
-
return
|
|
45377
|
+
return join7(dirname2(fileURLToPath(import.meta.url)), "runtime", "adapter.ts");
|
|
45339
45378
|
}
|
|
45340
45379
|
function runBuildHooks(hooks, cwd, onStep) {
|
|
45341
45380
|
for (const hook of hooks ?? []) {
|
|
@@ -45357,11 +45396,11 @@ async function packageServerlessApp(opts) {
|
|
|
45357
45396
|
const entry = app.entry;
|
|
45358
45397
|
if (!entry)
|
|
45359
45398
|
throw new Error("serverless app: `entry` is required to package a Node/Bun application");
|
|
45360
|
-
const entryPath =
|
|
45361
|
-
const stage = mkdtempSync(
|
|
45399
|
+
const entryPath = isAbsolute2(entry) ? entry : join7(projectRoot, entry);
|
|
45400
|
+
const stage = mkdtempSync(join7(tmpdir(), "tscloud-pkg-"));
|
|
45362
45401
|
try {
|
|
45363
|
-
cpSync(adapterSourcePath(),
|
|
45364
|
-
const bootstrapPath =
|
|
45402
|
+
cpSync(adapterSourcePath(), join7(stage, "adapter.ts"));
|
|
45403
|
+
const bootstrapPath = join7(stage, "bootstrap.ts");
|
|
45365
45404
|
writeFileSync3(bootstrapPath, generateBootstrap({ entryImport: entryPath, adapterImport: "./adapter" }));
|
|
45366
45405
|
opts.onStep?.("bundling application");
|
|
45367
45406
|
const result = await Bun.build({
|
|
@@ -46353,33 +46392,33 @@ CMD [ "index.http" ]
|
|
|
46353
46392
|
import { execFileSync } from "node:child_process";
|
|
46354
46393
|
import { mkdtempSync as mkdtempSync2, readFileSync as readFileSync4, rmSync as rmSync2 } from "node:fs";
|
|
46355
46394
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
46356
|
-
import { dirname as dirname3, join as
|
|
46395
|
+
import { dirname as dirname3, join as join8 } from "node:path";
|
|
46357
46396
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
46358
46397
|
function assetsDir() {
|
|
46359
46398
|
return dirname3(fileURLToPath2(import.meta.url));
|
|
46360
46399
|
}
|
|
46361
46400
|
function sharedRuntimeLoop() {
|
|
46362
|
-
return readFileSync4(
|
|
46401
|
+
return readFileSync4(join8(assetsDir(), "runtime.mjs"), "utf-8");
|
|
46363
46402
|
}
|
|
46364
46403
|
function bootstrap(kind) {
|
|
46365
|
-
return readFileSync4(
|
|
46404
|
+
return readFileSync4(join8(assetsDir(), `${kind}-bootstrap`), "utf-8");
|
|
46366
46405
|
}
|
|
46367
46406
|
function buildNodeRuntimeLayerZip(options) {
|
|
46368
46407
|
const architecture = options.architecture ?? "x86_64";
|
|
46369
46408
|
const nodeArch = architecture === "arm64" ? "arm64" : "x64";
|
|
46370
46409
|
const version = options.version.replace(/^v/, "");
|
|
46371
46410
|
const step = options.onStep ?? (() => {});
|
|
46372
|
-
const stage = mkdtempSync2(
|
|
46411
|
+
const stage = mkdtempSync2(join8(tmpdir2(), "tscloud-node-layer-"));
|
|
46373
46412
|
try {
|
|
46374
46413
|
const exact = version.includes(".") ? version : resolveLatestNode(version);
|
|
46375
46414
|
const dir = `node-v${exact}-linux-${nodeArch}`;
|
|
46376
46415
|
const url = `https://nodejs.org/dist/v${exact}/${dir}.tar.xz`;
|
|
46377
46416
|
step(`downloading Node ${exact} (${architecture})`);
|
|
46378
|
-
const tar =
|
|
46417
|
+
const tar = join8(stage, "node.tar.xz");
|
|
46379
46418
|
fetchToFile(url, tar);
|
|
46380
46419
|
step("extracting node binary");
|
|
46381
46420
|
execFileSync("tar", ["-xf", tar, "-C", stage, `${dir}/bin/node`], { stdio: "inherit" });
|
|
46382
|
-
const nodeBin = readFileSync4(
|
|
46421
|
+
const nodeBin = readFileSync4(join8(stage, dir, "bin", "node"));
|
|
46383
46422
|
step("packaging layer");
|
|
46384
46423
|
const entries = [
|
|
46385
46424
|
{ name: "bootstrap", data: bootstrap("node"), mode: 493 },
|
|
@@ -46396,15 +46435,15 @@ function buildBunRuntimeLayerZip(options) {
|
|
|
46396
46435
|
const bunArch = architecture === "arm64" ? "bun-linux-aarch64" : "bun-linux-x64";
|
|
46397
46436
|
const version = options.version === "latest" ? "" : options.version.replace(/^v/, "");
|
|
46398
46437
|
const step = options.onStep ?? (() => {});
|
|
46399
|
-
const stage = mkdtempSync2(
|
|
46438
|
+
const stage = mkdtempSync2(join8(tmpdir2(), "tscloud-bun-layer-"));
|
|
46400
46439
|
try {
|
|
46401
46440
|
const url = version ? `https://github.com/oven-sh/bun/releases/download/bun-v${version}/${bunArch}.zip` : `https://github.com/oven-sh/bun/releases/latest/download/${bunArch}.zip`;
|
|
46402
46441
|
step(`downloading Bun ${version || "latest"} (${architecture})`);
|
|
46403
|
-
const zipPath =
|
|
46442
|
+
const zipPath = join8(stage, "bun.zip");
|
|
46404
46443
|
fetchToFile(url, zipPath);
|
|
46405
46444
|
step("extracting bun binary");
|
|
46406
46445
|
execFileSync("unzip", ["-o", "-q", zipPath, "-d", stage], { stdio: "inherit" });
|
|
46407
|
-
const bunBin = readFileSync4(
|
|
46446
|
+
const bunBin = readFileSync4(join8(stage, bunArch, "bun"));
|
|
46408
46447
|
step("packaging layer");
|
|
46409
46448
|
const entries = [
|
|
46410
46449
|
{ name: "bootstrap", data: bootstrap("bun"), mode: 493 },
|
|
@@ -46589,14 +46628,14 @@ clear_env = no
|
|
|
46589
46628
|
}
|
|
46590
46629
|
// src/serverless-php/runtime-assets.ts
|
|
46591
46630
|
import { readFileSync as readFileSync5 } from "node:fs";
|
|
46592
|
-
import { dirname as dirname4, join as
|
|
46631
|
+
import { dirname as dirname4, join as join9 } from "node:path";
|
|
46593
46632
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
46594
46633
|
function assetsDir2() {
|
|
46595
|
-
return
|
|
46634
|
+
return join9(dirname4(fileURLToPath3(import.meta.url)), "runtime-assets");
|
|
46596
46635
|
}
|
|
46597
46636
|
function phpRuntimeLayerAssets() {
|
|
46598
46637
|
const dir = assetsDir2();
|
|
46599
|
-
const read = (f) => readFileSync5(
|
|
46638
|
+
const read = (f) => readFileSync5(join9(dir, f), "utf-8");
|
|
46600
46639
|
return [
|
|
46601
46640
|
{ path: "bootstrap", contents: read("bootstrap"), mode: 493 },
|
|
46602
46641
|
{ path: "tscloud/runtime.php", contents: read("runtime.php"), mode: 420 },
|
|
@@ -46635,10 +46674,10 @@ var LARAVEL_SERVERLESS_BUILD_STEPS = [
|
|
|
46635
46674
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
46636
46675
|
import { existsSync as existsSync5, mkdirSync as mkdirSync2, mkdtempSync as mkdtempSync3, readdirSync as readdirSync5, readFileSync as readFileSync6, rmSync as rmSync3, statSync as statSync3, writeFileSync as writeFileSync4 } from "node:fs";
|
|
46637
46676
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
46638
|
-
import { join as
|
|
46677
|
+
import { join as join10, relative as relative3 } from "node:path";
|
|
46639
46678
|
function* walk(dir) {
|
|
46640
46679
|
for (const entry of readdirSync5(dir)) {
|
|
46641
|
-
const full =
|
|
46680
|
+
const full = join10(dir, entry);
|
|
46642
46681
|
if (statSync3(full).isDirectory())
|
|
46643
46682
|
yield* walk(full);
|
|
46644
46683
|
else
|
|
@@ -46649,26 +46688,26 @@ function buildPhpRuntimeLayerZip(options = {}) {
|
|
|
46649
46688
|
const architecture = options.architecture ?? "x86_64";
|
|
46650
46689
|
const platform = options.platform ?? (architecture === "arm64" ? "linux/arm64" : "linux/amd64");
|
|
46651
46690
|
const step = options.onStep ?? (() => {});
|
|
46652
|
-
const stage = mkdtempSync3(
|
|
46691
|
+
const stage = mkdtempSync3(join10(tmpdir3(), "tscloud-php-layer-"));
|
|
46653
46692
|
const imageTag = "tscloud-php-layer:build";
|
|
46654
46693
|
try {
|
|
46655
|
-
writeFileSync4(
|
|
46694
|
+
writeFileSync4(join10(stage, "Dockerfile"), generatePhpLayerDockerfile(options));
|
|
46656
46695
|
step("Building PHP runtime image (docker)");
|
|
46657
46696
|
execFileSync2("docker", ["build", "--platform", platform, "-t", imageTag, stage], { stdio: "inherit" });
|
|
46658
46697
|
step("Extracting /opt/php from image");
|
|
46659
46698
|
const cid = execFileSync2("docker", ["create", "--platform", platform, imageTag], { encoding: "utf-8" }).trim();
|
|
46660
|
-
const optDir =
|
|
46699
|
+
const optDir = join10(stage, "opt");
|
|
46661
46700
|
mkdirSync2(optDir, { recursive: true });
|
|
46662
46701
|
try {
|
|
46663
|
-
execFileSync2("docker", ["cp", `${cid}:/opt/php`,
|
|
46702
|
+
execFileSync2("docker", ["cp", `${cid}:/opt/php`, join10(optDir, "php")], { stdio: "inherit" });
|
|
46664
46703
|
} finally {
|
|
46665
46704
|
execFileSync2("docker", ["rm", cid], { stdio: "ignore" });
|
|
46666
46705
|
}
|
|
46667
|
-
if (!existsSync5(
|
|
46706
|
+
if (!existsSync5(join10(optDir, "php", "bin", "php")))
|
|
46668
46707
|
throw new Error("layer build produced no /opt/php/bin/php");
|
|
46669
46708
|
const entries = [];
|
|
46670
46709
|
for (const file of walk(optDir)) {
|
|
46671
|
-
const rel =
|
|
46710
|
+
const rel = relative3(optDir, file).replace(/\\/g, "/");
|
|
46672
46711
|
const mode = statSync3(file).mode & 73 ? 493 : 420;
|
|
46673
46712
|
entries.push({ name: rel, data: readFileSync6(file), mode });
|
|
46674
46713
|
}
|
|
@@ -46689,7 +46728,7 @@ function buildPhpRuntimeLayerZip(options = {}) {
|
|
|
46689
46728
|
import { execSync as execSync2 } from "node:child_process";
|
|
46690
46729
|
import { createHash as createHash5 } from "node:crypto";
|
|
46691
46730
|
import { readdirSync as readdirSync6, readFileSync as readFileSync7, statSync as statSync4 } from "node:fs";
|
|
46692
|
-
import { join as
|
|
46731
|
+
import { join as join11, relative as relative4, resolve as resolve2 } from "node:path";
|
|
46693
46732
|
var PHP_DEFAULT_EXCLUDES = [
|
|
46694
46733
|
".git",
|
|
46695
46734
|
".github",
|
|
@@ -46710,8 +46749,8 @@ function isExcluded(rel, excludes) {
|
|
|
46710
46749
|
}
|
|
46711
46750
|
function* walk2(dir, root, excludes) {
|
|
46712
46751
|
for (const entry of readdirSync6(dir)) {
|
|
46713
|
-
const full =
|
|
46714
|
-
const rel =
|
|
46752
|
+
const full = join11(dir, entry);
|
|
46753
|
+
const rel = relative4(root, full).replace(/\\/g, "/");
|
|
46715
46754
|
if (isExcluded(rel, excludes))
|
|
46716
46755
|
continue;
|
|
46717
46756
|
if (statSync4(full).isDirectory())
|
|
@@ -46732,10 +46771,10 @@ function runPhpBuildHooks(opts) {
|
|
|
46732
46771
|
}
|
|
46733
46772
|
function collectPhpAppEntries(projectRoot, exclude = []) {
|
|
46734
46773
|
const root = resolve2(projectRoot);
|
|
46735
|
-
const excludes = [...PHP_DEFAULT_EXCLUDES, ...exclude];
|
|
46774
|
+
const excludes = [...PHP_DEFAULT_EXCLUDES, stateDir(), ...exclude];
|
|
46736
46775
|
const entries = [];
|
|
46737
46776
|
for (const file of walk2(root, root, excludes)) {
|
|
46738
|
-
const rel =
|
|
46777
|
+
const rel = relative4(root, file).replace(/\\/g, "/");
|
|
46739
46778
|
const executable = (statSync4(file).mode & 73) !== 0;
|
|
46740
46779
|
entries.push({ name: rel, data: readFileSync7(file), mode: executable ? 493 : 420 });
|
|
46741
46780
|
}
|
|
@@ -47226,11 +47265,14 @@ export {
|
|
|
47226
47265
|
suggestCommand,
|
|
47227
47266
|
storageAdvancedManager,
|
|
47228
47267
|
staticSiteManager,
|
|
47268
|
+
statePath,
|
|
47269
|
+
stateDir,
|
|
47229
47270
|
stackDependencyManager,
|
|
47230
47271
|
signRequestAsync,
|
|
47231
47272
|
signRequest,
|
|
47232
47273
|
sharedRuntimeLoop,
|
|
47233
47274
|
sha256,
|
|
47275
|
+
setStateDir,
|
|
47234
47276
|
serviceMeshManager,
|
|
47235
47277
|
sequence,
|
|
47236
47278
|
senderReputationManager,
|
|
@@ -47247,6 +47289,7 @@ export {
|
|
|
47247
47289
|
responseToResult,
|
|
47248
47290
|
resourceManagementManager,
|
|
47249
47291
|
resolveStorageBucketName,
|
|
47292
|
+
resolveStatePath,
|
|
47250
47293
|
resolveSiteStackName,
|
|
47251
47294
|
resolveSiteResourceName,
|
|
47252
47295
|
resolveSiteBucketName,
|
|
@@ -47309,6 +47352,7 @@ export {
|
|
|
47309
47352
|
lambdaConcurrencyManager,
|
|
47310
47353
|
isWebCryptoAvailable,
|
|
47311
47354
|
isValidRegion,
|
|
47355
|
+
isStatePath,
|
|
47312
47356
|
isNodeCryptoAvailable,
|
|
47313
47357
|
isManagementDashboardSiteName,
|
|
47314
47358
|
isLocalDevelopment,
|
|
@@ -47492,6 +47536,7 @@ export {
|
|
|
47492
47536
|
SecretsManager,
|
|
47493
47537
|
Secrets,
|
|
47494
47538
|
Search,
|
|
47539
|
+
STATE_DIR_ENV_VAR,
|
|
47495
47540
|
SMS,
|
|
47496
47541
|
S3Error,
|
|
47497
47542
|
S3Client,
|
|
@@ -47574,6 +47619,7 @@ export {
|
|
|
47574
47619
|
DNSSECManager,
|
|
47575
47620
|
DNS,
|
|
47576
47621
|
DLQMonitoringManager,
|
|
47622
|
+
DEFAULT_STATE_DIR,
|
|
47577
47623
|
DEFAULT_SERVICE_LIMITS,
|
|
47578
47624
|
DASHBOARD_STATE_DIR,
|
|
47579
47625
|
DASHBOARD_PORT_SPAN,
|
|
@@ -57,8 +57,16 @@ export interface ManagementDashboardOptions {
|
|
|
57
57
|
*/
|
|
58
58
|
version?: string;
|
|
59
59
|
}
|
|
60
|
-
/**
|
|
61
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Where the live dashboard keeps its users, session key and cache ON THE BOX,
|
|
62
|
+
* relative to its release directory.
|
|
63
|
+
*
|
|
64
|
+
* Deliberately the literal default rather than {@link stateDir}: that one is
|
|
65
|
+
* about the operator's machine (a Stacks checkout points it at `storage/cloud`),
|
|
66
|
+
* while this is the path the deploy carries across releases via `sharedPaths`.
|
|
67
|
+
* The two must agree with each other, not with the local checkout.
|
|
68
|
+
*/
|
|
69
|
+
export declare const DASHBOARD_STATE_DIR: string;
|
|
62
70
|
/**
|
|
63
71
|
* The dashboard service's entry point inside its release dir. The CLI is
|
|
64
72
|
* installed from npm by the release's `bun install`, so this path exists on the
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** The directory used when nothing configures one. */
|
|
2
|
+
export declare const DEFAULT_STATE_DIR = ".ts-cloud";
|
|
3
|
+
/** Environment variable that overrides both the config and the default. */
|
|
4
|
+
export declare const STATE_DIR_ENV_VAR = "TS_CLOUD_STATE_DIR";
|
|
5
|
+
/**
|
|
6
|
+
* Records the `stateDir` coming from `cloud.config.ts`.
|
|
7
|
+
*
|
|
8
|
+
* Called by the config loader. Passing a nullish or blank value clears it,
|
|
9
|
+
* which is what a config without `stateDir` should do — otherwise a stale value
|
|
10
|
+
* from a previously loaded config would leak into the next one (tests, and the
|
|
11
|
+
* dashboard server loading configs for several projects).
|
|
12
|
+
*/
|
|
13
|
+
export declare function setStateDir(dir?: string | null): void;
|
|
14
|
+
/**
|
|
15
|
+
* The configured state directory, as written — relative or absolute.
|
|
16
|
+
*/
|
|
17
|
+
export declare function stateDir(): string;
|
|
18
|
+
/**
|
|
19
|
+
* Joins segments onto the state directory without resolving it against a root.
|
|
20
|
+
*
|
|
21
|
+
* Use this for the exported "where does X live" helpers, whose value is a
|
|
22
|
+
* project-relative path that callers then resolve against their own `cwd`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function statePath(...segments: string[]): string;
|
|
25
|
+
/**
|
|
26
|
+
* Absolute path to a file or directory inside the state directory.
|
|
27
|
+
*
|
|
28
|
+
* An absolute {@link stateDir} wins over `cwd`, so a project can pin its state
|
|
29
|
+
* to a fixed location regardless of where a command is run from.
|
|
30
|
+
*/
|
|
31
|
+
export declare function resolveStatePath(cwd: string, ...segments: string[]): string;
|
|
32
|
+
/**
|
|
33
|
+
* Whether `path` is the state directory or something inside it.
|
|
34
|
+
*
|
|
35
|
+
* Everything that walks a project to package, hash, or ship it has to skip the
|
|
36
|
+
* state directory: it holds the dashboard credentials and the session key, and
|
|
37
|
+
* a deploy artifact that carries them is a credential leak. A hardcoded
|
|
38
|
+
* `.ts-cloud` check stops being enough the moment the directory is configurable,
|
|
39
|
+
* so ask this instead of comparing names.
|
|
40
|
+
*
|
|
41
|
+
* `path` may be absolute or relative to `root` (the project root, defaulting to
|
|
42
|
+
* the working directory).
|
|
43
|
+
*/
|
|
44
|
+
export declare function isStatePath(path: string, root?: string): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types.d.ts
CHANGED
|
@@ -155,6 +155,21 @@ export interface CloudConfig {
|
|
|
155
155
|
* Tags applied to all resources
|
|
156
156
|
*/
|
|
157
157
|
tags?: Record<string, string>;
|
|
158
|
+
/**
|
|
159
|
+
* Where ts-cloud keeps its machine-local state: dashboard credentials and
|
|
160
|
+
* session secret, the auth encryption key, the control-plane database, the
|
|
161
|
+
* staged dashboard release, cached templates, restore scratch space.
|
|
162
|
+
*
|
|
163
|
+
* Defaults to `.ts-cloud` in the project root. Point it at an existing home
|
|
164
|
+
* for runtime state to keep the root clean - a Stacks application sets
|
|
165
|
+
* `storage/cloud`. Relative paths resolve against the project root; absolute
|
|
166
|
+
* paths are used as-is. `TS_CLOUD_STATE_DIR` overrides this.
|
|
167
|
+
*
|
|
168
|
+
* Not to be confused with `storage/cloud/state/`, where the drivers record
|
|
169
|
+
* the provisioned box per stack - that one is meant to be committed so CI can
|
|
170
|
+
* find an existing server instead of provisioning a duplicate.
|
|
171
|
+
*/
|
|
172
|
+
stateDir?: string;
|
|
158
173
|
}
|
|
159
174
|
export type CloudOptions = Partial<CloudConfig>;
|
|
160
175
|
export interface ProjectConfig {
|
package/dist/utils/cache.d.ts
CHANGED
|
@@ -51,6 +51,15 @@ export declare class FileCache<T = any> {
|
|
|
51
51
|
private cacheDir;
|
|
52
52
|
private ttl;
|
|
53
53
|
constructor(cacheDir: string, options?: CacheOptions);
|
|
54
|
+
/**
|
|
55
|
+
* Create the cache directory, on the first write rather than on construction.
|
|
56
|
+
*
|
|
57
|
+
* Constructing a cache must not touch the filesystem: these objects get built
|
|
58
|
+
* eagerly at import time, before anything has had a chance to configure where
|
|
59
|
+
* state lives, and a directory created then lands in the wrong place and
|
|
60
|
+
* sticks around empty.
|
|
61
|
+
*/
|
|
62
|
+
private ensureCacheDir;
|
|
54
63
|
/**
|
|
55
64
|
* Get cache file path for key
|
|
56
65
|
*/
|
|
@@ -107,7 +116,4 @@ export declare class TemplateCache {
|
|
|
107
116
|
*/
|
|
108
117
|
prune(): void;
|
|
109
118
|
}
|
|
110
|
-
|
|
111
|
-
* Global template cache instance
|
|
112
|
-
*/
|
|
113
|
-
export declare const templateCache: TemplateCache;
|
|
119
|
+
export declare function templateCache(): TemplateCache;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ts-cloud/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.61",
|
|
5
5
|
"description": "Core CloudFormation generation library for ts-cloud",
|
|
6
6
|
"author": "Chris Breuer <chris@stacksjs.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"typecheck": "tsc --noEmit"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@ts-cloud/aws-types": "0.7.
|
|
34
|
+
"@ts-cloud/aws-types": "0.7.61"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"typescript": "^7.0.2"
|