@treeseed/sdk 0.1.1 → 0.3.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 +97 -494
- package/dist/{src/cli-tools.d.ts → cli-tools.d.ts} +1 -1
- package/dist/cli-tools.js +5 -3
- package/dist/{src/content-store.d.ts → content-store.d.ts} +3 -2
- package/dist/content-store.js +52 -20
- package/dist/{src/d1-store.d.ts → d1-store.d.ts} +62 -1
- package/dist/d1-store.js +625 -65
- package/dist/field-aliases.d.ts +11 -0
- package/dist/field-aliases.js +41 -0
- package/dist/graph/build.d.ts +19 -0
- package/dist/graph/build.js +949 -0
- package/dist/graph/dsl.d.ts +2 -0
- package/dist/graph/dsl.js +243 -0
- package/dist/graph/query.d.ts +47 -0
- package/dist/graph/query.js +447 -0
- package/dist/graph/ranking.d.ts +3 -0
- package/dist/graph/ranking.js +483 -0
- package/dist/graph/schema.d.ts +142 -0
- package/dist/graph/schema.js +133 -0
- package/dist/graph.d.ts +52 -0
- package/dist/graph.js +133 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +90 -2
- package/dist/model-registry.d.ts +8 -0
- package/dist/model-registry.js +351 -25
- package/dist/operations/providers/default.d.ts +10 -0
- package/dist/operations/providers/default.js +514 -0
- package/dist/operations/runtime.d.ts +7 -0
- package/dist/operations/runtime.js +60 -0
- package/dist/operations/services/config-runtime.d.ts +269 -0
- package/dist/operations/services/config-runtime.js +1397 -0
- package/dist/operations/services/d1-migration.d.ts +6 -0
- package/dist/operations/services/d1-migration.js +89 -0
- package/dist/operations/services/deploy.d.ts +371 -0
- package/dist/operations/services/deploy.js +981 -0
- package/dist/operations/services/git-workflow.d.ts +49 -0
- package/dist/operations/services/git-workflow.js +218 -0
- package/dist/operations/services/github-automation.d.ts +156 -0
- package/dist/operations/services/github-automation.js +256 -0
- package/dist/operations/services/local-dev.d.ts +9 -0
- package/dist/operations/services/local-dev.js +106 -0
- package/dist/operations/services/mailpit-runtime.d.ts +4 -0
- package/dist/operations/services/mailpit-runtime.js +59 -0
- package/dist/operations/services/railway-deploy.d.ts +53 -0
- package/dist/operations/services/railway-deploy.js +123 -0
- package/dist/operations/services/runtime-paths.d.ts +19 -0
- package/dist/operations/services/runtime-paths.js +54 -0
- package/dist/operations/services/runtime-tools.d.ts +117 -0
- package/dist/operations/services/runtime-tools.js +358 -0
- package/dist/operations/services/save-deploy-preflight.d.ts +34 -0
- package/dist/operations/services/save-deploy-preflight.js +76 -0
- package/dist/operations/services/template-registry.d.ts +88 -0
- package/dist/operations/services/template-registry.js +407 -0
- package/dist/operations/services/watch-dev.d.ts +21 -0
- package/dist/operations/services/watch-dev.js +284 -0
- package/dist/operations/services/workspace-preflight.d.ts +40 -0
- package/dist/operations/services/workspace-preflight.js +165 -0
- package/dist/operations/services/workspace-save.d.ts +42 -0
- package/dist/operations/services/workspace-save.js +235 -0
- package/dist/operations/services/workspace-tools.d.ts +16 -0
- package/dist/operations/services/workspace-tools.js +270 -0
- package/dist/operations-registry.d.ts +5 -0
- package/dist/operations-registry.js +68 -0
- package/dist/operations-types.d.ts +71 -0
- package/dist/operations-types.js +17 -0
- package/dist/operations.d.ts +6 -0
- package/dist/operations.js +16 -0
- package/dist/platform/books-data.d.ts +1 -0
- package/dist/platform/books-data.js +1 -0
- package/dist/platform/contracts.d.ts +158 -0
- package/dist/platform/contracts.js +0 -0
- package/dist/platform/deploy/config.d.ts +4 -0
- package/dist/platform/deploy/config.js +222 -0
- package/dist/platform/deploy-config.d.ts +1 -0
- package/dist/platform/deploy-config.js +1 -0
- package/dist/platform/env.yaml +394 -0
- package/dist/platform/environment.d.ts +130 -0
- package/dist/platform/environment.js +331 -0
- package/dist/platform/plugin.d.ts +2 -0
- package/dist/platform/plugin.js +4 -0
- package/dist/platform/plugins/constants.d.ts +22 -0
- package/dist/platform/plugins/constants.js +29 -0
- package/dist/platform/plugins/plugin.d.ts +51 -0
- package/dist/platform/plugins/plugin.js +6 -0
- package/dist/platform/plugins/runtime.d.ts +35 -0
- package/dist/platform/plugins/runtime.js +142 -0
- package/dist/platform/plugins.d.ts +5 -0
- package/dist/platform/plugins.js +16 -0
- package/dist/platform/site-config-schema.js +1 -0
- package/dist/platform/tenant/config.d.ts +9 -0
- package/dist/platform/tenant/config.js +154 -0
- package/dist/platform/tenant/runtime-config.d.ts +4 -0
- package/dist/platform/tenant/runtime-config.js +20 -0
- package/dist/platform/tenant-config.d.ts +1 -0
- package/dist/platform/tenant-config.js +1 -0
- package/dist/platform/utils/books-data.d.ts +29 -0
- package/dist/platform/utils/books-data.js +82 -0
- package/dist/platform/utils/site-config-schema.js +321 -0
- package/dist/remote.d.ts +175 -0
- package/dist/remote.js +202 -0
- package/dist/runtime.js +50 -3
- package/dist/scripts/aggregate-book.js +121 -0
- package/dist/scripts/build-dist.js +57 -13
- package/dist/scripts/build-tenant-worker.js +36 -0
- package/dist/scripts/cleanup-markdown.js +373 -0
- package/dist/scripts/cli-test-fixtures.js +48 -0
- package/dist/scripts/config-treeseed.js +95 -0
- package/dist/scripts/ensure-mailpit.js +29 -0
- package/dist/scripts/local-dev.js +129 -0
- package/dist/scripts/logs-mailpit.js +2 -0
- package/dist/scripts/patch-starlight-content-path.js +172 -0
- package/dist/scripts/release-verify.js +34 -5
- package/dist/scripts/run-fixture-astro-command.js +18 -0
- package/dist/scripts/scaffold-site.js +65 -0
- package/dist/scripts/stop-mailpit.js +5 -0
- package/dist/scripts/sync-dev-vars.js +6 -0
- package/dist/scripts/sync-template.js +20 -0
- package/dist/scripts/template-catalog.test.js +100 -0
- package/dist/scripts/template-command.js +31 -0
- package/dist/scripts/tenant-astro-command.js +3 -0
- package/dist/scripts/tenant-build.js +16 -0
- package/dist/scripts/tenant-check.js +7 -0
- package/dist/scripts/tenant-d1-migrate-local.js +11 -0
- package/dist/scripts/tenant-deploy.js +180 -0
- package/dist/scripts/tenant-destroy.js +104 -0
- package/dist/scripts/tenant-dev.js +171 -0
- package/dist/scripts/tenant-lint.js +4 -0
- package/dist/scripts/tenant-test.js +4 -0
- package/dist/scripts/test-cloudflare-local.js +212 -0
- package/dist/scripts/test-scaffold.js +314 -0
- package/dist/scripts/test-smoke.js +71 -13
- package/dist/scripts/treeseed-assert-release-tag-version.js +21 -0
- package/dist/scripts/treeseed-build-dist.js +134 -0
- package/dist/scripts/treeseed-publish-package.js +19 -0
- package/dist/scripts/treeseed-release-verify.js +131 -0
- package/dist/scripts/treeseed-run-ts.js +45 -0
- package/dist/scripts/validate-templates.js +6 -0
- package/dist/scripts/verify-driver.js +29 -0
- package/dist/scripts/workflow-commands.test.js +39 -0
- package/dist/scripts/workspace-close.js +24 -0
- package/dist/scripts/workspace-command-e2e.js +718 -0
- package/dist/scripts/workspace-lint.js +9 -0
- package/dist/scripts/workspace-preflight.js +22 -0
- package/dist/scripts/workspace-publish-changed-packages.js +16 -0
- package/dist/scripts/workspace-release-verify.js +81 -0
- package/dist/scripts/workspace-release.js +42 -0
- package/dist/scripts/workspace-save.js +124 -0
- package/dist/scripts/workspace-start-warning.js +3 -0
- package/dist/scripts/workspace-start.js +71 -0
- package/dist/scripts/workspace-test-unit.js +4 -0
- package/dist/scripts/workspace-test.js +11 -0
- package/dist/sdk-fields.d.ts +11 -0
- package/dist/sdk-fields.js +169 -0
- package/dist/sdk-filters.d.ts +4 -0
- package/dist/sdk-filters.js +12 -15
- package/dist/sdk-types.d.ts +796 -0
- package/dist/sdk-types.js +7 -1
- package/dist/sdk-version.d.ts +2 -0
- package/dist/sdk-version.js +42 -0
- package/dist/sdk.d.ts +215 -0
- package/dist/sdk.js +235 -11
- package/dist/stores/cursor-store.js +9 -3
- package/dist/stores/lease-store.js +8 -2
- package/dist/{src/stores → stores}/message-store.d.ts +1 -1
- package/dist/stores/message-store.js +27 -3
- package/dist/stores/operational-store.d.ts +24 -0
- package/dist/stores/operational-store.js +279 -0
- package/dist/stores/run-store.js +8 -1
- package/dist/stores/subscription-store.js +7 -5
- package/dist/template-catalog.d.ts +13 -0
- package/dist/template-catalog.js +141 -0
- package/dist/treeseed/services/compose.yml +7 -0
- package/dist/treeseed/template-catalog/catalog.fixture.json +55 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/astro.config.d.ts +2 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/astro.config.ts +3 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/package.json +32 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/config.yaml +40 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content/empty/.gitkeep +1 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content/knowledge/handbook/index.mdx +11 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content/pages/welcome.mdx +11 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content.config.d.ts +1 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content.config.ts +3 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/env.yaml +1 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/src/manifest.yaml +19 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/treeseed.site.yaml +26 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template/tsconfig.json +9 -0
- package/dist/treeseed/template-catalog/templates/starter-basic/template.config.json +90 -0
- package/dist/verification.d.ts +20 -0
- package/dist/verification.js +98 -0
- package/dist/workflow/operations.d.ts +396 -0
- package/dist/workflow/operations.js +841 -0
- package/dist/workflow-state.d.ts +56 -0
- package/dist/workflow-state.js +195 -0
- package/dist/workflow-support.d.ts +9 -0
- package/dist/workflow-support.js +176 -0
- package/dist/workflow.d.ts +111 -0
- package/dist/workflow.js +97 -0
- package/package.json +97 -5
- package/scripts/verify-driver.mjs +29 -0
- package/dist/scripts/.ts-run-1775616845195-odh4xzphk3l.js +0 -22
- package/dist/scripts/.ts-run-1775616848931-9386s6kwrl.js +0 -126
- package/dist/scripts/assert-release-tag-version.d.ts +0 -1
- package/dist/scripts/build-dist.d.ts +0 -1
- package/dist/scripts/package-tools.d.ts +0 -15
- package/dist/scripts/publish-package.d.ts +0 -1
- package/dist/scripts/release-verify.d.ts +0 -1
- package/dist/scripts/test-smoke.d.ts +0 -1
- package/dist/src/index.d.ts +0 -6
- package/dist/src/model-registry.d.ts +0 -4
- package/dist/src/sdk-filters.d.ts +0 -4
- package/dist/src/sdk-types.d.ts +0 -285
- package/dist/src/sdk.d.ts +0 -109
- package/dist/test/test-fixture.d.ts +0 -1
- package/dist/test/utils/envelopes.test.d.ts +0 -1
- package/dist/test/utils/sdk.test.d.ts +0 -1
- package/dist/vitest.config.d.ts +0 -2
- /package/dist/{src/frontmatter.d.ts → frontmatter.d.ts} +0 -0
- /package/dist/{src/git-runtime.d.ts → git-runtime.d.ts} +0 -0
- /package/dist/{src/runtime.d.ts → runtime.d.ts} +0 -0
- /package/dist/{src/stores → stores}/cursor-store.d.ts +0 -0
- /package/dist/{src/stores → stores}/envelopes.d.ts +0 -0
- /package/dist/{src/stores → stores}/helpers.d.ts +0 -0
- /package/dist/{src/stores → stores}/lease-store.d.ts +0 -0
- /package/dist/{src/stores → stores}/run-store.d.ts +0 -0
- /package/dist/{src/stores → stores}/subscription-store.d.ts +0 -0
- /package/dist/{src/types → types}/agents.d.ts +0 -0
- /package/dist/{src/types → types}/cloudflare.d.ts +0 -0
- /package/dist/{src/wrangler-d1.d.ts → wrangler-d1.d.ts} +0 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { cpSync, existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { dirname, join, resolve } from 'node:path';
|
|
5
|
+
import { spawnSync } from 'node:child_process';
|
|
6
|
+
import { agentPackageRoot, corePackageRoot, packageRoot, packageScriptPath, sdkPackageRoot } from '../operations/services/runtime-tools.js';
|
|
7
|
+
import { listTemplateProducts, validateTemplateProduct } from '../operations/services/template-registry.js';
|
|
8
|
+
const npmCacheDir = process.env.TREESEED_SCAFFOLD_NPM_CACHE_DIR
|
|
9
|
+
? resolve(process.env.TREESEED_SCAFFOLD_NPM_CACHE_DIR)
|
|
10
|
+
: resolve(tmpdir(), 'treeseed-npm-cache');
|
|
11
|
+
const packageJson = JSON.parse(readFileSync(resolve(corePackageRoot, 'package.json'), 'utf8'));
|
|
12
|
+
const sdkPackageJson = JSON.parse(readFileSync(resolve(sdkPackageRoot, 'package.json'), 'utf8'));
|
|
13
|
+
const cliPackageJson = JSON.parse(readFileSync(resolve(packageRoot, 'package.json'), 'utf8'));
|
|
14
|
+
const agentPackageJson = JSON.parse(readFileSync(resolve(agentPackageRoot, 'package.json'), 'utf8'));
|
|
15
|
+
const workspaceTarballs = (() => {
|
|
16
|
+
try {
|
|
17
|
+
return JSON.parse(process.env.TREESEED_WORKSPACE_TARBALLS ?? '{}');
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return {};
|
|
21
|
+
}
|
|
22
|
+
})();
|
|
23
|
+
const externalCoreTarball = process.env.TREESEED_SCAFFOLD_CORE_TARBALL
|
|
24
|
+
? resolve(process.env.TREESEED_SCAFFOLD_CORE_TARBALL)
|
|
25
|
+
: typeof workspaceTarballs['@treeseed/core'] === 'string'
|
|
26
|
+
? resolve(workspaceTarballs['@treeseed/core'])
|
|
27
|
+
: null;
|
|
28
|
+
const externalSdkTarball = process.env.TREESEED_SCAFFOLD_SDK_TARBALL
|
|
29
|
+
? resolve(process.env.TREESEED_SCAFFOLD_SDK_TARBALL)
|
|
30
|
+
: typeof workspaceTarballs['@treeseed/sdk'] === 'string'
|
|
31
|
+
? resolve(workspaceTarballs['@treeseed/sdk'])
|
|
32
|
+
: null;
|
|
33
|
+
const externalCliTarball = process.env.TREESEED_SCAFFOLD_CLI_TARBALL
|
|
34
|
+
? resolve(process.env.TREESEED_SCAFFOLD_CLI_TARBALL)
|
|
35
|
+
: typeof workspaceTarballs['@treeseed/cli'] === 'string'
|
|
36
|
+
? resolve(workspaceTarballs['@treeseed/cli'])
|
|
37
|
+
: null;
|
|
38
|
+
const externalAgentTarball = process.env.TREESEED_SCAFFOLD_AGENT_TARBALL
|
|
39
|
+
? resolve(process.env.TREESEED_SCAFFOLD_AGENT_TARBALL)
|
|
40
|
+
: typeof workspaceTarballs['@treeseed/agent'] === 'string'
|
|
41
|
+
? resolve(workspaceTarballs['@treeseed/agent'])
|
|
42
|
+
: null;
|
|
43
|
+
const reusesExternalTarballs = Boolean(externalCoreTarball || externalSdkTarball || externalCliTarball || externalAgentTarball);
|
|
44
|
+
const scaffoldChecks = new Set((process.env.TREESEED_SCAFFOLD_CHECKS ?? 'build,deploy')
|
|
45
|
+
.split(',')
|
|
46
|
+
.map((value) => value.trim())
|
|
47
|
+
.filter(Boolean));
|
|
48
|
+
const timings = [];
|
|
49
|
+
const resetScaffoldCache = process.env.TREESEED_SCAFFOLD_RESET_CACHE === '1';
|
|
50
|
+
const scaffoldTempRoot = resolve(process.env.TREESEED_SCAFFOLD_TEMP_ROOT ?? resolve(packageRoot, '.local', 'tmp'));
|
|
51
|
+
mkdirSync(scaffoldTempRoot, { recursive: true });
|
|
52
|
+
function logStep(message) {
|
|
53
|
+
console.log(`[treeseed:test-scaffold] ${message}`);
|
|
54
|
+
}
|
|
55
|
+
function withTiming(label, action) {
|
|
56
|
+
const startedAt = Date.now();
|
|
57
|
+
logStep(`${label} started`);
|
|
58
|
+
try {
|
|
59
|
+
const result = action();
|
|
60
|
+
if (result && typeof result.then === 'function') {
|
|
61
|
+
return result.then((resolved) => {
|
|
62
|
+
const durationMs = Date.now() - startedAt;
|
|
63
|
+
timings.push({ label, durationMs, status: 'completed' });
|
|
64
|
+
logStep(`${label} completed in ${(durationMs / 1000).toFixed(1)}s`);
|
|
65
|
+
return resolved;
|
|
66
|
+
}).catch((error) => {
|
|
67
|
+
const durationMs = Date.now() - startedAt;
|
|
68
|
+
timings.push({ label, durationMs, status: 'failed' });
|
|
69
|
+
logStep(`${label} failed in ${(durationMs / 1000).toFixed(1)}s`);
|
|
70
|
+
throw error;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
const durationMs = Date.now() - startedAt;
|
|
74
|
+
timings.push({ label, durationMs, status: 'completed' });
|
|
75
|
+
logStep(`${label} completed in ${(durationMs / 1000).toFixed(1)}s`);
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
const durationMs = Date.now() - startedAt;
|
|
80
|
+
timings.push({ label, durationMs, status: 'failed' });
|
|
81
|
+
logStep(`${label} failed in ${(durationMs / 1000).toFixed(1)}s`);
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function printSummary() {
|
|
86
|
+
if (timings.length === 0) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
console.log('[treeseed:test-scaffold] Stage summary');
|
|
90
|
+
for (const entry of timings) {
|
|
91
|
+
console.log(`[treeseed:test-scaffold] ${entry.status === 'completed' ? 'ok ' : 'fail'} ${entry.label} (${(entry.durationMs / 1000).toFixed(1)}s)`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function resetNpmCache() {
|
|
95
|
+
rmSync(npmCacheDir, { recursive: true, force: true });
|
|
96
|
+
}
|
|
97
|
+
function runStep(command, args, { cwd = packageRoot, env = {}, capture = false } = {}) {
|
|
98
|
+
const result = spawnSync(command, args, {
|
|
99
|
+
cwd,
|
|
100
|
+
env: { ...process.env, ...env },
|
|
101
|
+
stdio: capture ? 'pipe' : 'inherit',
|
|
102
|
+
encoding: 'utf8',
|
|
103
|
+
});
|
|
104
|
+
if (result.status !== 0) {
|
|
105
|
+
const message = capture ? (result.stderr?.trim() || result.stdout?.trim() || `${command} ${args.join(' ')} failed`) : `${command} ${args.join(' ')} failed`;
|
|
106
|
+
throw new Error(message);
|
|
107
|
+
}
|
|
108
|
+
return result;
|
|
109
|
+
}
|
|
110
|
+
function createTempSiteRoot() {
|
|
111
|
+
return mkdtempSync(join(scaffoldTempRoot, 'treeseed-scaffold-'));
|
|
112
|
+
}
|
|
113
|
+
function rewriteScaffoldDependency(siteRoot, tarballPath, cliTarballPath) {
|
|
114
|
+
const packageJsonPath = resolve(siteRoot, 'package.json');
|
|
115
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
116
|
+
packageJson.dependencies = packageJson.dependencies ?? {};
|
|
117
|
+
packageJson.dependencies['@treeseed/core'] = tarballPath;
|
|
118
|
+
packageJson.dependencies['@treeseed/cli'] = cliTarballPath;
|
|
119
|
+
writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`, 'utf8');
|
|
120
|
+
}
|
|
121
|
+
function installManualPackageTarball(siteRoot, tarballPath, packageName) {
|
|
122
|
+
const extractRoot = mkdtempSync(join(scaffoldTempRoot, 'treeseed-scaffold-package-'));
|
|
123
|
+
try {
|
|
124
|
+
runStep('tar', ['-xzf', tarballPath, '-C', extractRoot]);
|
|
125
|
+
const scopeRoot = resolve(siteRoot, 'node_modules', '@treeseed');
|
|
126
|
+
mkdirSync(scopeRoot, { recursive: true });
|
|
127
|
+
cpSync(resolve(extractRoot, 'package'), resolve(scopeRoot, packageName.split('/')[1]), { recursive: true });
|
|
128
|
+
}
|
|
129
|
+
finally {
|
|
130
|
+
rmSync(extractRoot, { recursive: true, force: true });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function linkWorkspacePackage(siteRoot, packageName, sourceRoot) {
|
|
134
|
+
const scopeRoot = resolve(siteRoot, 'node_modules', '@treeseed');
|
|
135
|
+
mkdirSync(scopeRoot, { recursive: true });
|
|
136
|
+
symlinkSync(sourceRoot, resolve(scopeRoot, packageName.split('/')[1]), 'dir');
|
|
137
|
+
}
|
|
138
|
+
function resolveSharedNodeModulesRoot() {
|
|
139
|
+
let current = packageRoot;
|
|
140
|
+
while (true) {
|
|
141
|
+
const candidate = resolve(current, 'node_modules');
|
|
142
|
+
if (existsSync(candidate)) {
|
|
143
|
+
return candidate;
|
|
144
|
+
}
|
|
145
|
+
const parent = resolve(current, '..');
|
|
146
|
+
if (parent === current) {
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
current = parent;
|
|
150
|
+
}
|
|
151
|
+
throw new Error(`Unable to locate a shared node_modules directory for ${packageRoot}.`);
|
|
152
|
+
}
|
|
153
|
+
function mirrorSharedNodeModules(siteRoot) {
|
|
154
|
+
const sharedNodeModules = resolveSharedNodeModulesRoot();
|
|
155
|
+
for (const entry of readdirSync(sharedNodeModules, { withFileTypes: true })) {
|
|
156
|
+
if (entry.name === '.bin' || entry.name === '@treeseed' || entry.name === '@astrojs') {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
const sourcePath = resolve(sharedNodeModules, entry.name);
|
|
160
|
+
const targetPath = resolve(siteRoot, 'node_modules', entry.name);
|
|
161
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
162
|
+
if (entry.name === 'astro') {
|
|
163
|
+
cpSync(sourcePath, targetPath, { recursive: true });
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
symlinkSync(sourcePath, targetPath, 'dir');
|
|
167
|
+
}
|
|
168
|
+
const sharedAstroScope = resolve(sharedNodeModules, '@astrojs');
|
|
169
|
+
const targetAstroScope = resolve(siteRoot, 'node_modules', '@astrojs');
|
|
170
|
+
mkdirSync(targetAstroScope, { recursive: true });
|
|
171
|
+
for (const packageName of ['cloudflare', 'mdx', 'sitemap', 'starlight']) {
|
|
172
|
+
cpSync(resolve(sharedAstroScope, packageName), resolve(targetAstroScope, packageName), { recursive: true });
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function linkTreeseedBins(siteRoot) {
|
|
176
|
+
const binRoot = resolve(siteRoot, 'node_modules', '.bin');
|
|
177
|
+
mkdirSync(binRoot, { recursive: true });
|
|
178
|
+
for (const [name, relativeTarget] of [
|
|
179
|
+
['treeseed', '../@treeseed/cli/dist/cli/main.js'],
|
|
180
|
+
['treeseed-agents', '../@treeseed/agent/dist/scripts/treeseed-agents.js'],
|
|
181
|
+
]) {
|
|
182
|
+
symlinkSync(relativeTarget, resolve(binRoot, name));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function createTarball(root, pkg) {
|
|
186
|
+
return withTiming(`${pkg.name} build+pack`, () => {
|
|
187
|
+
if (typeof pkg.scripts?.['build:dist'] === 'string') {
|
|
188
|
+
runStep('npm', ['run', 'build:dist'], { cwd: root });
|
|
189
|
+
}
|
|
190
|
+
const output = runStep('npm', ['pack', '--silent', '--ignore-scripts', '--cache', npmCacheDir], {
|
|
191
|
+
cwd: root,
|
|
192
|
+
capture: true,
|
|
193
|
+
env: {
|
|
194
|
+
npm_config_cache: npmCacheDir,
|
|
195
|
+
NPM_CONFIG_CACHE: npmCacheDir,
|
|
196
|
+
},
|
|
197
|
+
});
|
|
198
|
+
const filename = output.stdout
|
|
199
|
+
.split('\n')
|
|
200
|
+
.map((line) => line.trim())
|
|
201
|
+
.filter(Boolean)
|
|
202
|
+
.at(-1)
|
|
203
|
+
|| `${pkg.name.replace(/^@/, '').replaceAll('/', '-')}-${pkg.version}.tgz`;
|
|
204
|
+
return resolve(root, filename);
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
async function scaffoldSite(siteRoot) {
|
|
208
|
+
for (const definition of await listTemplateProducts({ writeWarning: (message) => console.warn(message) })) {
|
|
209
|
+
await validateTemplateProduct(definition, { writeWarning: (message) => console.warn(message) });
|
|
210
|
+
}
|
|
211
|
+
runStep(process.execPath, [packageScriptPath('scaffold-site'), siteRoot, '--template', 'starter-basic', '--name', 'Smoke Site', '--site-url', 'https://smoke.example.com', '--contact-email', 'hello@example.com']);
|
|
212
|
+
}
|
|
213
|
+
function installScaffold(siteRoot, { coreTarballPath, sdkTarballPath, cliTarballPath, agentTarballPath }) {
|
|
214
|
+
if (coreTarballPath && sdkTarballPath && cliTarballPath && agentTarballPath) {
|
|
215
|
+
linkWorkspacePackage(siteRoot, sdkPackageJson.name, sdkPackageRoot);
|
|
216
|
+
linkWorkspacePackage(siteRoot, packageJson.name, corePackageRoot);
|
|
217
|
+
linkWorkspacePackage(siteRoot, cliPackageJson.name, packageRoot);
|
|
218
|
+
linkWorkspacePackage(siteRoot, agentPackageJson.name, agentPackageRoot);
|
|
219
|
+
mirrorSharedNodeModules(siteRoot);
|
|
220
|
+
linkTreeseedBins(siteRoot);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
runStep('npm', ['install', '--cache', npmCacheDir, '--prefer-offline', '--no-audit', '--no-fund'], {
|
|
224
|
+
cwd: siteRoot,
|
|
225
|
+
env: {
|
|
226
|
+
npm_config_cache: npmCacheDir,
|
|
227
|
+
NPM_CONFIG_CACHE: npmCacheDir,
|
|
228
|
+
npm_config_prefer_offline: 'true',
|
|
229
|
+
npm_config_audit: 'false',
|
|
230
|
+
npm_config_fund: 'false',
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
function runScaffoldChecks(siteRoot) {
|
|
235
|
+
if (scaffoldChecks.has('build')) {
|
|
236
|
+
withTiming('scaffold build', () => {
|
|
237
|
+
runStep('npm', ['run', 'build'], { cwd: siteRoot });
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
if (scaffoldChecks.has('deploy')) {
|
|
241
|
+
withTiming('scaffold deploy dry-run', () => {
|
|
242
|
+
runStep('npm', ['run', 'deploy', '--', '--dry-run'], { cwd: siteRoot });
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
const siteRoot = createTempSiteRoot();
|
|
247
|
+
let tarballPath = externalCoreTarball;
|
|
248
|
+
let sdkTarballPath = externalSdkTarball;
|
|
249
|
+
let cliTarballPath = externalCliTarball;
|
|
250
|
+
let agentTarballPath = externalAgentTarball;
|
|
251
|
+
try {
|
|
252
|
+
if (!reusesExternalTarballs && resetScaffoldCache) {
|
|
253
|
+
logStep(`resetting npm cache at ${npmCacheDir}`);
|
|
254
|
+
resetNpmCache();
|
|
255
|
+
}
|
|
256
|
+
if (!sdkTarballPath) {
|
|
257
|
+
logStep('building and packing @treeseed/sdk');
|
|
258
|
+
sdkTarballPath = createTarball(sdkPackageRoot, sdkPackageJson);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
logStep(`reusing provided @treeseed/sdk tarball: ${sdkTarballPath}`);
|
|
262
|
+
}
|
|
263
|
+
if (!tarballPath) {
|
|
264
|
+
logStep('building and packing @treeseed/core');
|
|
265
|
+
tarballPath = createTarball(corePackageRoot, packageJson);
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
logStep(`reusing provided @treeseed/core tarball: ${tarballPath}`);
|
|
269
|
+
}
|
|
270
|
+
if (!agentTarballPath) {
|
|
271
|
+
logStep('building and packing @treeseed/agent');
|
|
272
|
+
agentTarballPath = createTarball(agentPackageRoot, agentPackageJson);
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
logStep(`reusing provided @treeseed/agent tarball: ${agentTarballPath}`);
|
|
276
|
+
}
|
|
277
|
+
if (!cliTarballPath) {
|
|
278
|
+
logStep('building and packing @treeseed/cli');
|
|
279
|
+
cliTarballPath = createTarball(packageRoot, cliPackageJson);
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
logStep(`reusing provided @treeseed/cli tarball: ${cliTarballPath}`);
|
|
283
|
+
}
|
|
284
|
+
logStep(`scaffolding temporary tenant at ${siteRoot}`);
|
|
285
|
+
await withTiming('scaffold tenant generation', async () => {
|
|
286
|
+
await scaffoldSite(siteRoot);
|
|
287
|
+
});
|
|
288
|
+
rewriteScaffoldDependency(siteRoot, tarballPath, cliTarballPath);
|
|
289
|
+
logStep(`installing scaffolded tenant dependencies with checks: ${[...scaffoldChecks].join(', ') || 'none'}`);
|
|
290
|
+
await withTiming('scaffold dependency install', async () => {
|
|
291
|
+
installScaffold(siteRoot, {
|
|
292
|
+
coreTarballPath: tarballPath,
|
|
293
|
+
sdkTarballPath,
|
|
294
|
+
cliTarballPath,
|
|
295
|
+
agentTarballPath,
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
logStep('running scaffold smoke checks');
|
|
299
|
+
runScaffoldChecks(siteRoot);
|
|
300
|
+
console.log(`Scaffold smoke test passed in ${dirname(siteRoot) ? siteRoot : '.'}`);
|
|
301
|
+
}
|
|
302
|
+
finally {
|
|
303
|
+
printSummary();
|
|
304
|
+
rmSync(siteRoot, { recursive: true, force: true });
|
|
305
|
+
if (sdkTarballPath && !externalSdkTarball) {
|
|
306
|
+
rmSync(sdkTarballPath, { force: true });
|
|
307
|
+
}
|
|
308
|
+
if (tarballPath && !externalCoreTarball) {
|
|
309
|
+
rmSync(tarballPath, { force: true });
|
|
310
|
+
}
|
|
311
|
+
if (!reusesExternalTarballs && resetScaffoldCache) {
|
|
312
|
+
resetNpmCache();
|
|
313
|
+
}
|
|
314
|
+
}
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
import { mkdirSync, readdirSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
|
|
1
|
+
import { chmodSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { mkdtempSync } from 'node:fs';
|
|
3
3
|
import { tmpdir } from 'node:os';
|
|
4
4
|
import { dirname, join, resolve } from 'node:path';
|
|
5
5
|
import { spawnSync } from 'node:child_process';
|
|
6
6
|
import { packageRoot } from './package-tools.js';
|
|
7
|
-
|
|
7
|
+
const npmCacheDir = resolve(tmpdir(), 'treeseed-npm-cache');
|
|
8
|
+
function run(command, args, cwd = packageRoot, capture = false, extraEnv = {}) {
|
|
8
9
|
const result = spawnSync(command, args, {
|
|
9
10
|
cwd,
|
|
10
11
|
stdio: capture ? 'pipe' : 'inherit',
|
|
11
12
|
encoding: 'utf8',
|
|
12
|
-
env:
|
|
13
|
+
env: {
|
|
14
|
+
...process.env,
|
|
15
|
+
...extraEnv,
|
|
16
|
+
npm_config_cache: npmCacheDir,
|
|
17
|
+
NPM_CONFIG_CACHE: npmCacheDir,
|
|
18
|
+
},
|
|
13
19
|
});
|
|
14
20
|
if (result.status !== 0) {
|
|
15
21
|
throw new Error(result.stderr?.trim() || result.stdout?.trim() || `${command} ${args.join(' ')} failed`);
|
|
@@ -17,13 +23,12 @@ function run(command, args, cwd = packageRoot, capture = false) {
|
|
|
17
23
|
return (result.stdout ?? '').trim();
|
|
18
24
|
}
|
|
19
25
|
function resolveNodeModulesRoot() {
|
|
20
|
-
let lastCandidate = null;
|
|
21
26
|
let current = packageRoot;
|
|
22
27
|
while (true) {
|
|
23
28
|
const candidate = resolve(current, 'node_modules');
|
|
24
29
|
try {
|
|
25
30
|
readdirSync(candidate);
|
|
26
|
-
|
|
31
|
+
return candidate;
|
|
27
32
|
}
|
|
28
33
|
catch {
|
|
29
34
|
}
|
|
@@ -32,15 +37,25 @@ function resolveNodeModulesRoot() {
|
|
|
32
37
|
break;
|
|
33
38
|
current = parent;
|
|
34
39
|
}
|
|
35
|
-
if (lastCandidate) {
|
|
36
|
-
return lastCandidate;
|
|
37
|
-
}
|
|
38
40
|
throw new Error(`Unable to locate node_modules for ${packageRoot}.`);
|
|
39
41
|
}
|
|
40
42
|
function mirrorDependencies(tempRoot) {
|
|
41
43
|
const sharedNodeModules = resolveNodeModulesRoot();
|
|
42
44
|
for (const entry of readdirSync(sharedNodeModules, { withFileTypes: true })) {
|
|
43
|
-
if (entry.name === '.bin'
|
|
45
|
+
if (entry.name === '.bin') {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (entry.name === '@treeseed') {
|
|
49
|
+
const sourceScopeRoot = resolve(sharedNodeModules, entry.name);
|
|
50
|
+
const targetScopeRoot = resolve(tempRoot, 'node_modules', entry.name);
|
|
51
|
+
mkdirSync(targetScopeRoot, { recursive: true });
|
|
52
|
+
for (const scopedEntry of readdirSync(sourceScopeRoot, { withFileTypes: true })) {
|
|
53
|
+
if (scopedEntry.name === 'sdk') {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const targetPath = resolve(targetScopeRoot, scopedEntry.name);
|
|
57
|
+
symlinkSync(resolve(sourceScopeRoot, scopedEntry.name), targetPath, scopedEntry.isDirectory() ? 'dir' : 'file');
|
|
58
|
+
}
|
|
44
59
|
continue;
|
|
45
60
|
}
|
|
46
61
|
const targetPath = resolve(tempRoot, 'node_modules', entry.name);
|
|
@@ -48,6 +63,34 @@ function mirrorDependencies(tempRoot) {
|
|
|
48
63
|
symlinkSync(resolve(sharedNodeModules, entry.name), targetPath, 'dir');
|
|
49
64
|
}
|
|
50
65
|
}
|
|
66
|
+
function resolveInstalledSdkRoot(installRoot) {
|
|
67
|
+
const directRoot = resolve(installRoot, 'node_modules', '@treeseed', 'sdk');
|
|
68
|
+
const nestedRoot = resolve(directRoot, 'package');
|
|
69
|
+
if (existsSync(resolve(directRoot, 'package.json'))) {
|
|
70
|
+
return directRoot;
|
|
71
|
+
}
|
|
72
|
+
if (existsSync(resolve(nestedRoot, 'package.json'))) {
|
|
73
|
+
return nestedRoot;
|
|
74
|
+
}
|
|
75
|
+
throw new Error('Unable to locate installed SDK package root in smoke test.');
|
|
76
|
+
}
|
|
77
|
+
function loadPackedSdkPackageJson(installRoot) {
|
|
78
|
+
return JSON.parse(readFileSync(resolve(resolveInstalledSdkRoot(installRoot), 'package.json'), 'utf8'));
|
|
79
|
+
}
|
|
80
|
+
function wireSdkBin(installRoot) {
|
|
81
|
+
const packageJson = loadPackedSdkPackageJson(installRoot);
|
|
82
|
+
const relativeBinPath = packageJson.bin?.['treeseed-sdk-verify'];
|
|
83
|
+
if (!relativeBinPath) {
|
|
84
|
+
throw new Error('Packed SDK is missing treeseed-sdk-verify bin metadata.');
|
|
85
|
+
}
|
|
86
|
+
const binRoot = resolve(installRoot, 'node_modules', '.bin');
|
|
87
|
+
const target = resolve(resolveInstalledSdkRoot(installRoot), relativeBinPath);
|
|
88
|
+
const linkPath = resolve(binRoot, 'treeseed-sdk-verify');
|
|
89
|
+
mkdirSync(binRoot, { recursive: true });
|
|
90
|
+
symlinkSync(target, linkPath);
|
|
91
|
+
chmodSync(target, 0o755);
|
|
92
|
+
return linkPath;
|
|
93
|
+
}
|
|
51
94
|
const stageRoot = mkdtempSync(join(tmpdir(), 'treeseed-sdk-smoke-'));
|
|
52
95
|
const packRoot = resolve(stageRoot, 'pack');
|
|
53
96
|
const extractRoot = resolve(stageRoot, 'extract');
|
|
@@ -55,11 +98,17 @@ const installRoot = resolve(stageRoot, 'install');
|
|
|
55
98
|
try {
|
|
56
99
|
mkdirSync(packRoot, { recursive: true });
|
|
57
100
|
mkdirSync(extractRoot, { recursive: true });
|
|
58
|
-
const
|
|
101
|
+
const packOutput = run('npm', ['pack', '--ignore-scripts', '--cache', npmCacheDir, '--pack-destination', packRoot], packageRoot, true);
|
|
102
|
+
const filename = packOutput
|
|
59
103
|
.split('\n')
|
|
60
104
|
.map((line) => line.trim())
|
|
61
105
|
.filter(Boolean)
|
|
62
|
-
.at(-1)
|
|
106
|
+
.at(-1)
|
|
107
|
+
?? readdirSync(packRoot, { withFileTypes: true })
|
|
108
|
+
.filter((entry) => entry.isFile() && entry.name.endsWith('.tgz'))
|
|
109
|
+
.map((entry) => entry.name)
|
|
110
|
+
.sort((left, right) => left.localeCompare(right, undefined, { numeric: true, sensitivity: 'base' }))
|
|
111
|
+
.at(-1);
|
|
63
112
|
if (!filename) {
|
|
64
113
|
throw new Error('Unable to determine packed SDK tarball name.');
|
|
65
114
|
}
|
|
@@ -68,8 +117,17 @@ try {
|
|
|
68
117
|
mkdirSync(resolve(installRoot, 'node_modules', '@treeseed'), { recursive: true });
|
|
69
118
|
run('cp', ['-R', resolve(extractRoot, 'package'), resolve(installRoot, 'node_modules', '@treeseed', 'sdk')]);
|
|
70
119
|
mirrorDependencies(installRoot);
|
|
71
|
-
|
|
72
|
-
|
|
120
|
+
const verifyBin = wireSdkBin(installRoot);
|
|
121
|
+
writeFileSync(resolve(installRoot, 'package.json'), `${JSON.stringify({
|
|
122
|
+
name: 'treeseed-sdk-smoke',
|
|
123
|
+
private: true,
|
|
124
|
+
type: 'module',
|
|
125
|
+
scripts: {
|
|
126
|
+
'verify:direct': 'node --input-type=module -e "console.log(\'treeseed-sdk-smoke-verify\')"',
|
|
127
|
+
},
|
|
128
|
+
}, null, 2)}\n`, 'utf8');
|
|
129
|
+
run(process.execPath, ['--input-type=module', '-e', 'await import("@treeseed/sdk/verification");'], installRoot);
|
|
130
|
+
run(verifyBin, [], installRoot, false, { TREESEED_VERIFY_DRIVER: 'direct' });
|
|
73
131
|
console.log('SDK packed-install smoke passed.');
|
|
74
132
|
}
|
|
75
133
|
finally {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const packageRoot = resolve(fileURLToPath(new URL('..', import.meta.url)));
|
|
5
|
+
const packageJson = JSON.parse(readFileSync(resolve(packageRoot, 'package.json'), 'utf8'));
|
|
6
|
+
const packageVersion = packageJson.version;
|
|
7
|
+
const tagName = process.argv[2] || process.env.GITHUB_REF_NAME;
|
|
8
|
+
if (!tagName) {
|
|
9
|
+
console.error('Release tag validation requires a tag name argument or GITHUB_REF_NAME.');
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
if (!/^\d+\.\d+\.\d+$/.test(tagName)) {
|
|
13
|
+
console.error(`Release tag "${tagName}" must use plain semver format "x.y.z".`);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
const taggedVersion = tagName;
|
|
17
|
+
if (taggedVersion !== packageVersion) {
|
|
18
|
+
console.error(`Release tag version "${taggedVersion}" does not match @treeseed/cli version "${packageVersion}".`);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
console.log(`Release tag "${tagName}" matches @treeseed/cli version "${packageVersion}".`);
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync, chmodSync } from 'node:fs';
|
|
2
|
+
import { basename, dirname, extname, join, relative, resolve } from 'node:path';
|
|
3
|
+
import { build } from 'esbuild';
|
|
4
|
+
import ts from 'typescript';
|
|
5
|
+
import { packageRoot } from './package-tools.js';
|
|
6
|
+
const srcRoot = resolve(packageRoot, 'src');
|
|
7
|
+
const scriptsRoot = resolve(packageRoot, 'scripts');
|
|
8
|
+
const distRoot = resolve(packageRoot, 'dist');
|
|
9
|
+
const templateCatalogSourceRoot = resolve(srcRoot, 'template-catalog');
|
|
10
|
+
const COPY_EXTENSIONS = new Set(['.json', '.md']);
|
|
11
|
+
function walkFiles(root) {
|
|
12
|
+
const files = [];
|
|
13
|
+
for (const entry of readdirSync(root, { withFileTypes: true })) {
|
|
14
|
+
const fullPath = join(root, entry.name);
|
|
15
|
+
if (entry.isDirectory())
|
|
16
|
+
files.push(...walkFiles(fullPath));
|
|
17
|
+
else
|
|
18
|
+
files.push(fullPath);
|
|
19
|
+
}
|
|
20
|
+
return files;
|
|
21
|
+
}
|
|
22
|
+
function ensureDir(filePath) {
|
|
23
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
function rewriteRuntimeSpecifiers(contents, outputFile = null) {
|
|
26
|
+
let rewritten = contents
|
|
27
|
+
.replace(/(['"`])(\.[^'"`\n]+)\.(mjs|ts)\1/g, '$1$2.js$1')
|
|
28
|
+
.replace(/(['"`])\.\.\/src\//g, '$1../');
|
|
29
|
+
if (!outputFile || outputFile.includes(`${resolve(distRoot, 'scripts')}`)) {
|
|
30
|
+
return rewritten;
|
|
31
|
+
}
|
|
32
|
+
rewritten = rewritten.replace(/(['"`])((?:\.\.\/)+scripts\/([^'"`\n]+))\1/g, (_match, quote, _specifier, scriptPath) => {
|
|
33
|
+
const targetPath = resolve(distRoot, 'scripts', scriptPath);
|
|
34
|
+
let relativeSpecifier = relative(dirname(outputFile), targetPath).replaceAll('\\', '/');
|
|
35
|
+
if (!relativeSpecifier.startsWith('.')) {
|
|
36
|
+
relativeSpecifier = `./${relativeSpecifier}`;
|
|
37
|
+
}
|
|
38
|
+
return `${quote}${relativeSpecifier}${quote}`;
|
|
39
|
+
});
|
|
40
|
+
return rewritten;
|
|
41
|
+
}
|
|
42
|
+
function isTypeScriptSource(filePath) {
|
|
43
|
+
return filePath.endsWith('.ts') && !filePath.endsWith('.d.js');
|
|
44
|
+
}
|
|
45
|
+
async function compileModule(filePath, sourceRoot, outputRoot) {
|
|
46
|
+
const relativePath = relative(sourceRoot, filePath);
|
|
47
|
+
const outputFile = resolve(outputRoot, relativePath.replace(/\.(mjs|ts)$/u, '.js'));
|
|
48
|
+
ensureDir(outputFile);
|
|
49
|
+
await build({
|
|
50
|
+
entryPoints: [filePath],
|
|
51
|
+
outfile: outputFile,
|
|
52
|
+
platform: 'node',
|
|
53
|
+
format: 'esm',
|
|
54
|
+
bundle: false,
|
|
55
|
+
logLevel: 'silent',
|
|
56
|
+
});
|
|
57
|
+
const builtSource = readFileSync(outputFile, 'utf8');
|
|
58
|
+
writeFileSync(outputFile, rewriteRuntimeSpecifiers(builtSource, outputFile), 'utf8');
|
|
59
|
+
}
|
|
60
|
+
function copyAsset(filePath, sourceRoot, outputRoot) {
|
|
61
|
+
const outputFile = resolve(outputRoot, relative(sourceRoot, filePath));
|
|
62
|
+
ensureDir(outputFile);
|
|
63
|
+
copyFileSync(filePath, outputFile);
|
|
64
|
+
if (outputFile.endsWith('.d.js')) {
|
|
65
|
+
writeFileSync(outputFile, rewriteRuntimeSpecifiers(readFileSync(outputFile, 'utf8')), 'utf8');
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function copyAssetTree(sourceRoot, outputRoot) {
|
|
69
|
+
for (const filePath of walkFiles(sourceRoot)) {
|
|
70
|
+
copyAsset(filePath, sourceRoot, outputRoot);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function transpileScript(filePath) {
|
|
74
|
+
if (basename(filePath).startsWith('.ts-run-')) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const source = readFileSync(filePath, 'utf8');
|
|
78
|
+
const relativePath = relative(scriptsRoot, filePath);
|
|
79
|
+
const outputFile = resolve(distRoot, 'scripts', relativePath.replace(/\.(mjs|ts)$/u, '.js'));
|
|
80
|
+
const transformed = extname(filePath) === '.ts'
|
|
81
|
+
? ts.transpileModule(source, {
|
|
82
|
+
compilerOptions: { module: ts.ModuleKind.ESNext, target: ts.ScriptTarget.ES2022 },
|
|
83
|
+
}).outputText
|
|
84
|
+
: source;
|
|
85
|
+
ensureDir(outputFile);
|
|
86
|
+
writeFileSync(outputFile, rewriteRuntimeSpecifiers(transformed, outputFile), 'utf8');
|
|
87
|
+
chmodSync(outputFile, 0o755);
|
|
88
|
+
}
|
|
89
|
+
function emitDeclarations() {
|
|
90
|
+
const rootNames = walkFiles(srcRoot).filter(isTypeScriptSource);
|
|
91
|
+
const program = ts.createProgram({
|
|
92
|
+
rootNames,
|
|
93
|
+
options: {
|
|
94
|
+
allowImportingTsExtensions: true,
|
|
95
|
+
target: ts.ScriptTarget.ES2022,
|
|
96
|
+
module: ts.ModuleKind.ESNext,
|
|
97
|
+
moduleResolution: ts.ModuleResolutionKind.Bundler,
|
|
98
|
+
strict: true,
|
|
99
|
+
types: ['node'],
|
|
100
|
+
declaration: true,
|
|
101
|
+
emitDeclarationOnly: true,
|
|
102
|
+
declarationDir: distRoot,
|
|
103
|
+
rootDir: srcRoot,
|
|
104
|
+
noEmit: false,
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
const result = program.emit();
|
|
108
|
+
if (result.emitSkipped) {
|
|
109
|
+
throw new Error('Declaration build failed.');
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
rmSync(distRoot, { recursive: true, force: true });
|
|
113
|
+
for (const filePath of walkFiles(srcRoot)) {
|
|
114
|
+
if (filePath.startsWith(`${templateCatalogSourceRoot}/`)) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
const extension = extname(filePath);
|
|
118
|
+
if (isTypeScriptSource(filePath))
|
|
119
|
+
await compileModule(filePath, srcRoot, distRoot);
|
|
120
|
+
else if (COPY_EXTENSIONS.has(extension))
|
|
121
|
+
copyAsset(filePath, srcRoot, distRoot);
|
|
122
|
+
}
|
|
123
|
+
if (existsSync(templateCatalogSourceRoot)) {
|
|
124
|
+
copyAssetTree(templateCatalogSourceRoot, resolve(distRoot, 'template-catalog'));
|
|
125
|
+
}
|
|
126
|
+
for (const filePath of walkFiles(scriptsRoot)) {
|
|
127
|
+
const extension = extname(filePath);
|
|
128
|
+
if (extension === '.ts' || extension === '.mjs')
|
|
129
|
+
transpileScript(filePath);
|
|
130
|
+
}
|
|
131
|
+
emitDeclarations();
|
|
132
|
+
if (existsSync(resolve(packageRoot, 'README.md'))) {
|
|
133
|
+
copyFileSync(resolve(packageRoot, 'README.md'), resolve(distRoot, '..', 'README.md'));
|
|
134
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const packageRoot = resolve(fileURLToPath(new URL('..', import.meta.url)));
|
|
5
|
+
const extraArgs = process.argv.slice(2);
|
|
6
|
+
const npmArgs = ['publish', '.', '--access', 'public'];
|
|
7
|
+
if (process.env.GITHUB_ACTIONS === 'true')
|
|
8
|
+
npmArgs.push('--provenance');
|
|
9
|
+
npmArgs.push(...extraArgs);
|
|
10
|
+
const result = spawnSync('npm', npmArgs, {
|
|
11
|
+
cwd: packageRoot,
|
|
12
|
+
stdio: 'inherit',
|
|
13
|
+
env: process.env,
|
|
14
|
+
});
|
|
15
|
+
if (result.error) {
|
|
16
|
+
console.error(result.error.message);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
process.exit(result.status ?? 1);
|