@edge-base/cli 0.1.1
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 +182 -0
- package/dist/commands/admin.d.ts +10 -0
- package/dist/commands/admin.d.ts.map +1 -0
- package/dist/commands/admin.js +307 -0
- package/dist/commands/admin.js.map +1 -0
- package/dist/commands/backup.d.ts +148 -0
- package/dist/commands/backup.d.ts.map +1 -0
- package/dist/commands/backup.js +1247 -0
- package/dist/commands/backup.js.map +1 -0
- package/dist/commands/completion.d.ts +3 -0
- package/dist/commands/completion.d.ts.map +1 -0
- package/dist/commands/completion.js +168 -0
- package/dist/commands/completion.js.map +1 -0
- package/dist/commands/create-plugin.d.ts +3 -0
- package/dist/commands/create-plugin.d.ts.map +1 -0
- package/dist/commands/create-plugin.js +208 -0
- package/dist/commands/create-plugin.js.map +1 -0
- package/dist/commands/deploy.d.ts +146 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +1823 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/describe.d.ts +45 -0
- package/dist/commands/describe.d.ts.map +1 -0
- package/dist/commands/describe.js +114 -0
- package/dist/commands/describe.js.map +1 -0
- package/dist/commands/destroy.d.ts +13 -0
- package/dist/commands/destroy.d.ts.map +1 -0
- package/dist/commands/destroy.js +642 -0
- package/dist/commands/destroy.js.map +1 -0
- package/dist/commands/dev.d.ts +80 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +1131 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/docker.d.ts +22 -0
- package/dist/commands/docker.d.ts.map +1 -0
- package/dist/commands/docker.js +373 -0
- package/dist/commands/docker.js.map +1 -0
- package/dist/commands/export.d.ts +15 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +142 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/init.d.ts +7 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +506 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/keys.d.ts +23 -0
- package/dist/commands/keys.d.ts.map +1 -0
- package/dist/commands/keys.js +347 -0
- package/dist/commands/keys.js.map +1 -0
- package/dist/commands/logs.d.ts +17 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +104 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/migrate.d.ts +29 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +302 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/migration.d.ts +18 -0
- package/dist/commands/migration.d.ts.map +1 -0
- package/dist/commands/migration.js +114 -0
- package/dist/commands/migration.js.map +1 -0
- package/dist/commands/neon.d.ts +66 -0
- package/dist/commands/neon.d.ts.map +1 -0
- package/dist/commands/neon.js +600 -0
- package/dist/commands/neon.js.map +1 -0
- package/dist/commands/plugins.d.ts +9 -0
- package/dist/commands/plugins.d.ts.map +1 -0
- package/dist/commands/plugins.js +295 -0
- package/dist/commands/plugins.js.map +1 -0
- package/dist/commands/realtime.d.ts +3 -0
- package/dist/commands/realtime.d.ts.map +1 -0
- package/dist/commands/realtime.js +71 -0
- package/dist/commands/realtime.js.map +1 -0
- package/dist/commands/secret.d.ts +7 -0
- package/dist/commands/secret.d.ts.map +1 -0
- package/dist/commands/secret.js +180 -0
- package/dist/commands/secret.js.map +1 -0
- package/dist/commands/seed.d.ts +21 -0
- package/dist/commands/seed.d.ts.map +1 -0
- package/dist/commands/seed.js +325 -0
- package/dist/commands/seed.js.map +1 -0
- package/dist/commands/telemetry.d.ts +12 -0
- package/dist/commands/telemetry.d.ts.map +1 -0
- package/dist/commands/telemetry.js +57 -0
- package/dist/commands/telemetry.js.map +1 -0
- package/dist/commands/typegen.d.ts +26 -0
- package/dist/commands/typegen.d.ts.map +1 -0
- package/dist/commands/typegen.js +212 -0
- package/dist/commands/typegen.js.map +1 -0
- package/dist/commands/upgrade.d.ts +29 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +265 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/commands/webhook-test.d.ts +3 -0
- package/dist/commands/webhook-test.d.ts.map +1 -0
- package/dist/commands/webhook-test.js +133 -0
- package/dist/commands/webhook-test.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +183 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/agent-contract.d.ts +36 -0
- package/dist/lib/agent-contract.d.ts.map +1 -0
- package/dist/lib/agent-contract.js +78 -0
- package/dist/lib/agent-contract.js.map +1 -0
- package/dist/lib/cf-auth.d.ts +76 -0
- package/dist/lib/cf-auth.d.ts.map +1 -0
- package/dist/lib/cf-auth.js +321 -0
- package/dist/lib/cf-auth.js.map +1 -0
- package/dist/lib/cli-context.d.ts +23 -0
- package/dist/lib/cli-context.d.ts.map +1 -0
- package/dist/lib/cli-context.js +40 -0
- package/dist/lib/cli-context.js.map +1 -0
- package/dist/lib/cloudflare-deploy-manifest.d.ts +26 -0
- package/dist/lib/cloudflare-deploy-manifest.d.ts.map +1 -0
- package/dist/lib/cloudflare-deploy-manifest.js +107 -0
- package/dist/lib/cloudflare-deploy-manifest.js.map +1 -0
- package/dist/lib/cloudflare-wrangler-resources.d.ts +32 -0
- package/dist/lib/cloudflare-wrangler-resources.d.ts.map +1 -0
- package/dist/lib/cloudflare-wrangler-resources.js +59 -0
- package/dist/lib/cloudflare-wrangler-resources.js.map +1 -0
- package/dist/lib/config-editor.d.ts +139 -0
- package/dist/lib/config-editor.d.ts.map +1 -0
- package/dist/lib/config-editor.js +1188 -0
- package/dist/lib/config-editor.js.map +1 -0
- package/dist/lib/deploy-shared.d.ts +55 -0
- package/dist/lib/deploy-shared.d.ts.map +1 -0
- package/dist/lib/deploy-shared.js +183 -0
- package/dist/lib/deploy-shared.js.map +1 -0
- package/dist/lib/dev-sidecar.d.ts +31 -0
- package/dist/lib/dev-sidecar.d.ts.map +1 -0
- package/dist/lib/dev-sidecar.js +1058 -0
- package/dist/lib/dev-sidecar.js.map +1 -0
- package/dist/lib/fetch-with-timeout.d.ts +14 -0
- package/dist/lib/fetch-with-timeout.d.ts.map +1 -0
- package/dist/lib/fetch-with-timeout.js +29 -0
- package/dist/lib/fetch-with-timeout.js.map +1 -0
- package/dist/lib/function-registry.d.ts +56 -0
- package/dist/lib/function-registry.d.ts.map +1 -0
- package/dist/lib/function-registry.js +210 -0
- package/dist/lib/function-registry.js.map +1 -0
- package/dist/lib/load-config.d.ts +24 -0
- package/dist/lib/load-config.d.ts.map +1 -0
- package/dist/lib/load-config.js +263 -0
- package/dist/lib/load-config.js.map +1 -0
- package/dist/lib/local-secrets.d.ts +2 -0
- package/dist/lib/local-secrets.d.ts.map +1 -0
- package/dist/lib/local-secrets.js +60 -0
- package/dist/lib/local-secrets.js.map +1 -0
- package/dist/lib/managed-resource-names.d.ts +4 -0
- package/dist/lib/managed-resource-names.d.ts.map +1 -0
- package/dist/lib/managed-resource-names.js +19 -0
- package/dist/lib/managed-resource-names.js.map +1 -0
- package/dist/lib/migrator.d.ts +57 -0
- package/dist/lib/migrator.d.ts.map +1 -0
- package/dist/lib/migrator.js +321 -0
- package/dist/lib/migrator.js.map +1 -0
- package/dist/lib/neon.d.ts +41 -0
- package/dist/lib/neon.d.ts.map +1 -0
- package/dist/lib/neon.js +325 -0
- package/dist/lib/neon.js.map +1 -0
- package/dist/lib/node-tools.d.ts +10 -0
- package/dist/lib/node-tools.d.ts.map +1 -0
- package/dist/lib/node-tools.js +32 -0
- package/dist/lib/node-tools.js.map +1 -0
- package/dist/lib/npm.d.ts +8 -0
- package/dist/lib/npm.d.ts.map +1 -0
- package/dist/lib/npm.js +10 -0
- package/dist/lib/npm.js.map +1 -0
- package/dist/lib/npx.d.ts +9 -0
- package/dist/lib/npx.d.ts.map +1 -0
- package/dist/lib/npx.js +11 -0
- package/dist/lib/npx.js.map +1 -0
- package/dist/lib/project-runtime.d.ts +38 -0
- package/dist/lib/project-runtime.d.ts.map +1 -0
- package/dist/lib/project-runtime.js +122 -0
- package/dist/lib/project-runtime.js.map +1 -0
- package/dist/lib/prompts.d.ts +28 -0
- package/dist/lib/prompts.d.ts.map +1 -0
- package/dist/lib/prompts.js +85 -0
- package/dist/lib/prompts.js.map +1 -0
- package/dist/lib/rate-limit-bindings.d.ts +11 -0
- package/dist/lib/rate-limit-bindings.d.ts.map +1 -0
- package/dist/lib/rate-limit-bindings.js +52 -0
- package/dist/lib/rate-limit-bindings.js.map +1 -0
- package/dist/lib/realtime-provision.d.ts +22 -0
- package/dist/lib/realtime-provision.d.ts.map +1 -0
- package/dist/lib/realtime-provision.js +246 -0
- package/dist/lib/realtime-provision.js.map +1 -0
- package/dist/lib/resolve-options.d.ts +42 -0
- package/dist/lib/resolve-options.d.ts.map +1 -0
- package/dist/lib/resolve-options.js +98 -0
- package/dist/lib/resolve-options.js.map +1 -0
- package/dist/lib/runtime-scaffold.d.ts +17 -0
- package/dist/lib/runtime-scaffold.d.ts.map +1 -0
- package/dist/lib/runtime-scaffold.js +366 -0
- package/dist/lib/runtime-scaffold.js.map +1 -0
- package/dist/lib/schema-check.d.ts +79 -0
- package/dist/lib/schema-check.d.ts.map +1 -0
- package/dist/lib/schema-check.js +347 -0
- package/dist/lib/schema-check.js.map +1 -0
- package/dist/lib/spinner.d.ts +20 -0
- package/dist/lib/spinner.d.ts.map +1 -0
- package/dist/lib/spinner.js +42 -0
- package/dist/lib/spinner.js.map +1 -0
- package/dist/lib/telemetry.d.ts +37 -0
- package/dist/lib/telemetry.d.ts.map +1 -0
- package/dist/lib/telemetry.js +98 -0
- package/dist/lib/telemetry.js.map +1 -0
- package/dist/lib/turnstile-provision.d.ts +27 -0
- package/dist/lib/turnstile-provision.d.ts.map +1 -0
- package/dist/lib/turnstile-provision.js +144 -0
- package/dist/lib/turnstile-provision.js.map +1 -0
- package/dist/lib/update-check.d.ts +13 -0
- package/dist/lib/update-check.d.ts.map +1 -0
- package/dist/lib/update-check.js +110 -0
- package/dist/lib/update-check.js.map +1 -0
- package/dist/lib/wrangler-secrets.d.ts +3 -0
- package/dist/lib/wrangler-secrets.d.ts.map +1 -0
- package/dist/lib/wrangler-secrets.js +32 -0
- package/dist/lib/wrangler-secrets.js.map +1 -0
- package/dist/lib/wrangler.d.ts +9 -0
- package/dist/lib/wrangler.d.ts.map +1 -0
- package/dist/lib/wrangler.js +84 -0
- package/dist/lib/wrangler.js.map +1 -0
- package/dist/templates/plugin/README.md.tmpl +91 -0
- package/dist/templates/plugin/client/js/package.json.tmpl +23 -0
- package/dist/templates/plugin/client/js/src/index.ts.tmpl +68 -0
- package/dist/templates/plugin/client/js/tsconfig.json.tmpl +14 -0
- package/dist/templates/plugin/server/package.json.tmpl +19 -0
- package/dist/templates/plugin/server/src/index.ts.tmpl +59 -0
- package/dist/templates/plugin/server/tsconfig.json.tmpl +14 -0
- package/llms.txt +94 -0
- package/package.json +60 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { npxCommand } from './npx.js';
|
|
6
|
+
import { listWranglerSecretNames } from './wrangler-secrets.js';
|
|
7
|
+
/**
|
|
8
|
+
* Provision Cloudflare Turnstile widget via Management API.
|
|
9
|
+
* If config.captcha === true: auto-create widget, store secret.
|
|
10
|
+
* If config.captcha is CaptchaConfig: use provided keys.
|
|
11
|
+
*
|
|
12
|
+
* @returns { siteKey, secretKey } or null if captcha not configured.
|
|
13
|
+
*/
|
|
14
|
+
export async function provisionTurnstile(captchaConfig, projectDir, _configJson, knownAccountId) {
|
|
15
|
+
if (!captchaConfig)
|
|
16
|
+
return null;
|
|
17
|
+
if (typeof captchaConfig === 'object') {
|
|
18
|
+
console.log(chalk.green('✓'), 'Captcha: using manual siteKey/secretKey');
|
|
19
|
+
return {
|
|
20
|
+
siteKey: captchaConfig.siteKey,
|
|
21
|
+
secretKey: captchaConfig.secretKey,
|
|
22
|
+
managed: false,
|
|
23
|
+
source: 'manual',
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
console.log(chalk.blue('🛡️ Provisioning Cloudflare Turnstile...'));
|
|
27
|
+
const cfAccountId = knownAccountId ??
|
|
28
|
+
process.env.CLOUDFLARE_ACCOUNT_ID ??
|
|
29
|
+
(() => {
|
|
30
|
+
const wranglerPath = join(projectDir, 'wrangler.toml');
|
|
31
|
+
if (existsSync(wranglerPath)) {
|
|
32
|
+
const content = readFileSync(wranglerPath, 'utf-8');
|
|
33
|
+
const match = content.match(/account_id\s*=\s*"([^"]+)"/);
|
|
34
|
+
return match?.[1];
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
})();
|
|
38
|
+
const apiToken = process.env.CLOUDFLARE_API_TOKEN;
|
|
39
|
+
if (!cfAccountId || !apiToken) {
|
|
40
|
+
console.log(chalk.yellow('⚠'), 'Turnstile auto-provisioning requires CLOUDFLARE_API_TOKEN env var.');
|
|
41
|
+
console.log(chalk.dim(' Set captcha to { siteKey, secretKey } in config for manual mode.'));
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
let projectName = 'edgebase';
|
|
45
|
+
const wranglerPath = join(projectDir, 'wrangler.toml');
|
|
46
|
+
if (existsSync(wranglerPath)) {
|
|
47
|
+
const content = readFileSync(wranglerPath, 'utf-8');
|
|
48
|
+
const nameMatch = content.match(/^name\s*=\s*"([^"]+)"/m);
|
|
49
|
+
if (nameMatch)
|
|
50
|
+
projectName = nameMatch[1];
|
|
51
|
+
}
|
|
52
|
+
const widgetName = `${projectName}-captcha`;
|
|
53
|
+
try {
|
|
54
|
+
const listResp = await fetch(`https://api.cloudflare.com/client/v4/accounts/${cfAccountId}/challenges/widgets`, { headers: { Authorization: `Bearer ${apiToken}` } });
|
|
55
|
+
const listResult = (await listResp.json());
|
|
56
|
+
const widgets = listResult?.result ?? [];
|
|
57
|
+
const existing = widgets.find((w) => w.name === widgetName);
|
|
58
|
+
if (existing) {
|
|
59
|
+
console.log(chalk.dim(` Turnstile widget '${widgetName}': already exists → ${existing.sitekey.slice(0, 8)}…`));
|
|
60
|
+
storeSecretIfMissing(projectDir, 'TURNSTILE_SECRET', existing.secret);
|
|
61
|
+
return {
|
|
62
|
+
siteKey: existing.sitekey,
|
|
63
|
+
secretKey: existing.secret,
|
|
64
|
+
widgetName,
|
|
65
|
+
managed: true,
|
|
66
|
+
source: 'existing',
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const createResp = await fetch(`https://api.cloudflare.com/client/v4/accounts/${cfAccountId}/challenges/widgets`, {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
headers: {
|
|
72
|
+
Authorization: `Bearer ${apiToken}`,
|
|
73
|
+
'Content-Type': 'application/json',
|
|
74
|
+
},
|
|
75
|
+
body: JSON.stringify({ name: widgetName, domains: ['*'], mode: 'managed' }),
|
|
76
|
+
});
|
|
77
|
+
const createResult = (await createResp.json());
|
|
78
|
+
if (createResult?.success && createResult.result) {
|
|
79
|
+
const { sitekey, secret } = createResult.result;
|
|
80
|
+
console.log(chalk.green('✓'), `Turnstile widget '${widgetName}': created → ${sitekey.slice(0, 8)}…`);
|
|
81
|
+
storeSecretIfMissing(projectDir, 'TURNSTILE_SECRET', secret);
|
|
82
|
+
return {
|
|
83
|
+
siteKey: sitekey,
|
|
84
|
+
secretKey: secret,
|
|
85
|
+
widgetName,
|
|
86
|
+
managed: true,
|
|
87
|
+
source: 'created',
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const errors = createResult?.errors?.map((e) => e.message).join(', ') ??
|
|
91
|
+
'unknown error';
|
|
92
|
+
console.log(chalk.yellow('⚠'), `Turnstile widget creation failed: ${errors}`);
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
97
|
+
console.log(chalk.yellow('⚠'), `Turnstile provisioning failed: ${msg}`);
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Store a Workers secret if not already set.
|
|
103
|
+
*/
|
|
104
|
+
export function storeSecretIfMissing(projectDir, secretName, secretValue) {
|
|
105
|
+
try {
|
|
106
|
+
const secretNames = listWranglerSecretNames(projectDir);
|
|
107
|
+
if (!secretNames.has(secretName)) {
|
|
108
|
+
execFileSync(npxCommand(), ['wrangler', 'secret', 'put', secretName], {
|
|
109
|
+
cwd: projectDir,
|
|
110
|
+
input: secretValue,
|
|
111
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
112
|
+
});
|
|
113
|
+
console.log(chalk.green('✓'), `${secretName} stored as Workers secret.`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
console.log(chalk.yellow('⚠'), `Could not store ${secretName} as Workers secret. Set it manually via: npx wrangler secret put ${secretName}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Inject captcha siteKey as a standalone CAPTCHA_SITE_KEY variable in wrangler.toml [vars].
|
|
122
|
+
*/
|
|
123
|
+
export function injectCaptchaSiteKey(wranglerPath, siteKey) {
|
|
124
|
+
if (!existsSync(wranglerPath))
|
|
125
|
+
return;
|
|
126
|
+
let content = readFileSync(wranglerPath, 'utf-8');
|
|
127
|
+
try {
|
|
128
|
+
if (content.includes('CAPTCHA_SITE_KEY')) {
|
|
129
|
+
content = content.replace(/CAPTCHA_SITE_KEY\s*=\s*"[^"]*"/, `CAPTCHA_SITE_KEY = "${siteKey}"`);
|
|
130
|
+
}
|
|
131
|
+
else if (content.includes('[vars]')) {
|
|
132
|
+
content = content.replace('[vars]', `[vars]\nCAPTCHA_SITE_KEY = "${siteKey}"`);
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
content += `\n[vars]\nCAPTCHA_SITE_KEY = "${siteKey}"\n`;
|
|
136
|
+
}
|
|
137
|
+
writeFileSync(wranglerPath, content, 'utf-8');
|
|
138
|
+
console.log(chalk.green('✓'), 'Captcha siteKey injected as CAPTCHA_SITE_KEY in wrangler.toml');
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
console.log(chalk.yellow('⚠'), 'Could not inject CAPTCHA_SITE_KEY into wrangler.toml');
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=turnstile-provision.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turnstile-provision.js","sourceRoot":"","sources":["../../src/lib/turnstile-provision.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Update notifier — checks npm registry for newer versions.
|
|
3
|
+
*
|
|
4
|
+
* - Caches results in ~/.edgebase/update-check.json (24h TTL)
|
|
5
|
+
* - Non-blocking: failures are silently ignored
|
|
6
|
+
* - Skipped in quiet/json mode and CI environments
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Check for available updates and print banner if outdated.
|
|
10
|
+
* Safe to call at program exit — all errors are swallowed.
|
|
11
|
+
*/
|
|
12
|
+
export declare function checkForUpdates(currentVersion: string): void;
|
|
13
|
+
//# sourceMappingURL=update-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-check.d.ts","sourceRoot":"","sources":["../../src/lib/update-check.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmEH;;;GAGG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAmC5D"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Update notifier — checks npm registry for newer versions.
|
|
3
|
+
*
|
|
4
|
+
* - Caches results in ~/.edgebase/update-check.json (24h TTL)
|
|
5
|
+
* - Non-blocking: failures are silently ignored
|
|
6
|
+
* - Skipped in quiet/json mode and CI environments
|
|
7
|
+
*/
|
|
8
|
+
import { execFileSync } from 'node:child_process';
|
|
9
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
10
|
+
import { join, dirname } from 'node:path';
|
|
11
|
+
import { homedir } from 'node:os';
|
|
12
|
+
import chalk from 'chalk';
|
|
13
|
+
import { parseSemver, semverDiff } from '../commands/upgrade.js';
|
|
14
|
+
import { isQuiet } from './cli-context.js';
|
|
15
|
+
import { npmCommand } from './npm.js';
|
|
16
|
+
const CHECK_INTERVAL = 24 * 60 * 60 * 1000; // 24 hours
|
|
17
|
+
const UPDATE_CHECK_PACKAGE_NAME = '@edge-base/cli';
|
|
18
|
+
function updateCheckDir() {
|
|
19
|
+
return join(homedir(), '.edgebase');
|
|
20
|
+
}
|
|
21
|
+
function updateCheckFile() {
|
|
22
|
+
return join(updateCheckDir(), 'update-check.json');
|
|
23
|
+
}
|
|
24
|
+
function loadCachedUpdate() {
|
|
25
|
+
try {
|
|
26
|
+
const cacheFile = updateCheckFile();
|
|
27
|
+
if (!existsSync(cacheFile))
|
|
28
|
+
return null;
|
|
29
|
+
const cache = JSON.parse(readFileSync(cacheFile, 'utf-8'));
|
|
30
|
+
if (typeof cache.latest !== 'string' || typeof cache.checkedAt !== 'number')
|
|
31
|
+
return null;
|
|
32
|
+
return {
|
|
33
|
+
latest: cache.latest,
|
|
34
|
+
checkedAt: cache.checkedAt,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function saveCachedUpdate(latest) {
|
|
42
|
+
try {
|
|
43
|
+
const cacheFile = updateCheckFile();
|
|
44
|
+
const cacheDir = dirname(cacheFile);
|
|
45
|
+
if (!existsSync(cacheDir))
|
|
46
|
+
mkdirSync(cacheDir, { recursive: true });
|
|
47
|
+
writeFileSync(cacheFile, JSON.stringify({ latest, checkedAt: Date.now() }));
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// Cache writes are best-effort only.
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function isNewerVersion(current, candidate) {
|
|
54
|
+
const [cMajor, cMinor, cPatch] = parseSemver(current);
|
|
55
|
+
const [nMajor, nMinor, nPatch] = parseSemver(candidate);
|
|
56
|
+
if (nMajor !== cMajor)
|
|
57
|
+
return nMajor > cMajor;
|
|
58
|
+
if (nMinor !== cMinor)
|
|
59
|
+
return nMinor > cMinor;
|
|
60
|
+
return nPatch > cPatch;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Check for available updates and print banner if outdated.
|
|
64
|
+
* Safe to call at program exit — all errors are swallowed.
|
|
65
|
+
*/
|
|
66
|
+
export function checkForUpdates(currentVersion) {
|
|
67
|
+
if (isQuiet())
|
|
68
|
+
return;
|
|
69
|
+
// Skip in CI environments
|
|
70
|
+
if (process.env.CI || process.env.CONTINUOUS_INTEGRATION)
|
|
71
|
+
return;
|
|
72
|
+
const cache = loadCachedUpdate();
|
|
73
|
+
if (cache && Date.now() - cache.checkedAt < CHECK_INTERVAL) {
|
|
74
|
+
if (cache.latest &&
|
|
75
|
+
isNewerVersion(currentVersion, cache.latest) &&
|
|
76
|
+
semverDiff(currentVersion, cache.latest) !== 'none') {
|
|
77
|
+
printUpdateBanner(currentVersion, cache.latest);
|
|
78
|
+
}
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
// Query npm registry (3s timeout to avoid blocking)
|
|
83
|
+
const latest = execFileSync(npmCommand(), ['show', UPDATE_CHECK_PACKAGE_NAME, 'version'], {
|
|
84
|
+
encoding: 'utf-8',
|
|
85
|
+
stdio: ['pipe', 'pipe', 'ignore'],
|
|
86
|
+
timeout: 3000,
|
|
87
|
+
}).trim();
|
|
88
|
+
if (!latest)
|
|
89
|
+
return;
|
|
90
|
+
saveCachedUpdate(latest);
|
|
91
|
+
if (isNewerVersion(currentVersion, latest) && semverDiff(currentVersion, latest) !== 'none') {
|
|
92
|
+
printUpdateBanner(currentVersion, latest);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// Network failure, npm not found, etc. — silently ignore
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function printUpdateBanner(current, latest) {
|
|
100
|
+
const msg1 = ` Update available: ${current} → ${latest} `;
|
|
101
|
+
const msg2 = ` Run ${chalk.cyan('npx edgebase upgrade')} to update `;
|
|
102
|
+
const width = Math.max(msg1.length, msg2.length) + 2;
|
|
103
|
+
const border = '─'.repeat(width);
|
|
104
|
+
console.log();
|
|
105
|
+
console.log(chalk.yellow(`╭${border}╮`));
|
|
106
|
+
console.log(chalk.yellow('│') + msg1.padEnd(width) + chalk.yellow('│'));
|
|
107
|
+
console.log(chalk.yellow('│') + msg2.padEnd(width) + chalk.yellow('│'));
|
|
108
|
+
console.log(chalk.yellow(`╰${border}╯`));
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=update-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../../src/lib/update-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrangler-secrets.d.ts","sourceRoot":"","sources":["../../src/lib/wrangler-secrets.ts"],"names":[],"mappings":"AAWA,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAoBpE;AAED,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAYvE"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { wranglerArgs, wranglerCommand } from './wrangler.js';
|
|
3
|
+
function isObject(value) {
|
|
4
|
+
return typeof value === 'object' && value !== null;
|
|
5
|
+
}
|
|
6
|
+
export function parseWranglerSecretNames(output) {
|
|
7
|
+
const parsed = JSON.parse(output);
|
|
8
|
+
const entries = Array.isArray(parsed)
|
|
9
|
+
? parsed
|
|
10
|
+
: isObject(parsed) && Array.isArray(parsed.result)
|
|
11
|
+
? parsed.result
|
|
12
|
+
: null;
|
|
13
|
+
if (!entries) {
|
|
14
|
+
throw new Error('Unexpected Wrangler secret list format.');
|
|
15
|
+
}
|
|
16
|
+
const names = new Set();
|
|
17
|
+
for (const entry of entries) {
|
|
18
|
+
if (typeof entry?.name === 'string') {
|
|
19
|
+
names.add(entry.name);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return names;
|
|
23
|
+
}
|
|
24
|
+
export function listWranglerSecretNames(projectDir) {
|
|
25
|
+
const output = execFileSync(wranglerCommand(), wranglerArgs(['wrangler', 'secret', 'list', '--format', 'json']), {
|
|
26
|
+
cwd: projectDir,
|
|
27
|
+
encoding: 'utf-8',
|
|
28
|
+
stdio: ['ignore', 'pipe', 'ignore'],
|
|
29
|
+
});
|
|
30
|
+
return parseWranglerSecretNames(output);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=wrangler-secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrangler-secrets.js","sourceRoot":"","sources":["../../src/lib/wrangler-secrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAM9D,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,MAAc;IACrD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAY,CAAC;IAC7C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QACnC,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC;YAChD,CAAC,CAAC,MAAM,CAAC,MAAM;YACf,CAAC,CAAC,IAAI,CAAC;IAEX,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,OAAoC,EAAE,CAAC;QACzD,IAAI,OAAO,KAAK,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;YACpC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,UAAkB;IACxD,MAAM,MAAM,GAAG,YAAY,CACzB,eAAe,EAAE,EACjB,YAAY,CAAC,CAAC,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,EAChE;QACE,GAAG,EAAE,UAAU;QACf,QAAQ,EAAE,OAAO;QACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;KACpC,CACF,CAAC;IAEF,OAAO,wBAAwB,CAAC,MAAM,CAAC,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare function resolveWranglerBinPath(baseDir?: string): string;
|
|
2
|
+
export declare function resolveWranglerTool(baseDir?: string): {
|
|
3
|
+
command: string;
|
|
4
|
+
argsPrefix: string[];
|
|
5
|
+
};
|
|
6
|
+
export declare function wranglerCommand(): string;
|
|
7
|
+
export declare function wranglerArgs(args: string[]): string[];
|
|
8
|
+
export declare function wranglerHint(args: string[]): string;
|
|
9
|
+
//# sourceMappingURL=wrangler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrangler.d.ts","sourceRoot":"","sources":["../../src/lib/wrangler.ts"],"names":[],"mappings":"AAuDA,wBAAgB,sBAAsB,CAAC,OAAO,SAAgB,GAAG,MAAM,CAetE;AAED,wBAAgB,mBAAmB,CACjC,OAAO,SAAgB,GACtB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAA;CAAE,CAa3C;AAMD,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAErD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAEnD"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { existsSync, readFileSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { dirname, join, resolve } from 'node:path';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
function normalizeWranglerArgs(args) {
|
|
8
|
+
return args[0] === 'wrangler' ? args.slice(1) : args;
|
|
9
|
+
}
|
|
10
|
+
function findWranglerPackageJsonFrom(baseDir) {
|
|
11
|
+
let cursor = resolve(baseDir);
|
|
12
|
+
while (true) {
|
|
13
|
+
const direct = join(cursor, 'node_modules', 'wrangler', 'package.json');
|
|
14
|
+
if (existsSync(direct)) {
|
|
15
|
+
return direct;
|
|
16
|
+
}
|
|
17
|
+
const pnpmDir = join(cursor, 'node_modules', '.pnpm');
|
|
18
|
+
if (existsSync(pnpmDir)) {
|
|
19
|
+
const candidate = readdirSync(pnpmDir)
|
|
20
|
+
.filter((entry) => entry.startsWith('wrangler@'))
|
|
21
|
+
.map((entry) => join(pnpmDir, entry, 'node_modules', 'wrangler', 'package.json'))
|
|
22
|
+
.find((entry) => existsSync(entry));
|
|
23
|
+
if (candidate) {
|
|
24
|
+
return candidate;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const parent = dirname(cursor);
|
|
28
|
+
if (parent === cursor) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
cursor = parent;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function resolveWranglerPackageJson(baseDir = process.cwd()) {
|
|
35
|
+
return findWranglerPackageJsonFrom(baseDir)
|
|
36
|
+
?? (() => {
|
|
37
|
+
try {
|
|
38
|
+
return require.resolve('wrangler/package.json');
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return findWranglerPackageJsonFrom(moduleDir);
|
|
42
|
+
}
|
|
43
|
+
})();
|
|
44
|
+
}
|
|
45
|
+
export function resolveWranglerBinPath(baseDir = process.cwd()) {
|
|
46
|
+
const packageJsonPath = resolveWranglerPackageJson(baseDir);
|
|
47
|
+
if (!packageJsonPath) {
|
|
48
|
+
throw new Error('Could not locate wrangler/package.json in this workspace.');
|
|
49
|
+
}
|
|
50
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
51
|
+
const relBin = typeof packageJson.bin === 'string'
|
|
52
|
+
? packageJson.bin
|
|
53
|
+
: packageJson.bin?.wrangler ?? packageJson.bin?.wrangler2;
|
|
54
|
+
if (!relBin) {
|
|
55
|
+
throw new Error('Could not resolve Wrangler bin entry.');
|
|
56
|
+
}
|
|
57
|
+
return resolve(dirname(packageJsonPath), relBin);
|
|
58
|
+
}
|
|
59
|
+
export function resolveWranglerTool(baseDir = process.cwd()) {
|
|
60
|
+
const packageJsonPath = resolveWranglerPackageJson(baseDir);
|
|
61
|
+
if (!packageJsonPath) {
|
|
62
|
+
return {
|
|
63
|
+
command: process.platform === 'win32' ? 'npx.cmd' : 'npx',
|
|
64
|
+
argsPrefix: ['wrangler'],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
command: process.execPath,
|
|
69
|
+
argsPrefix: [resolveWranglerBinPath(baseDir)],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function resolveWranglerBin() {
|
|
73
|
+
return resolveWranglerBinPath(process.cwd());
|
|
74
|
+
}
|
|
75
|
+
export function wranglerCommand() {
|
|
76
|
+
return process.execPath;
|
|
77
|
+
}
|
|
78
|
+
export function wranglerArgs(args) {
|
|
79
|
+
return [resolveWranglerBin(), ...normalizeWranglerArgs(args)];
|
|
80
|
+
}
|
|
81
|
+
export function wranglerHint(args) {
|
|
82
|
+
return `${wranglerCommand()} ${wranglerArgs(args).join(' ')}`;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=wrangler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrangler.js","sourceRoot":"","sources":["../../src/lib/wrangler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# {{PLUGIN_NAME}}
|
|
2
|
+
|
|
3
|
+
EdgeBase plugin for {{PLUGIN_DESCRIPTION}}.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install {{PLUGIN_NAME}} # server plugin
|
|
9
|
+
npm install {{PLUGIN_NAME}}-client @edge-base/web # optional typed web client
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Configuration
|
|
13
|
+
|
|
14
|
+
Add the plugin to your `edgebase.config.ts`:
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
import { {{PLUGIN_NAME_CAMEL}}Plugin } from '{{PLUGIN_NAME}}';
|
|
18
|
+
|
|
19
|
+
export default defineConfig({
|
|
20
|
+
plugins: [
|
|
21
|
+
{{PLUGIN_NAME_CAMEL}}Plugin({
|
|
22
|
+
apiKey: process.env.MY_PLUGIN_API_KEY!,
|
|
23
|
+
}),
|
|
24
|
+
],
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
### Client SDK
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { createClient } from '@edge-base/web';
|
|
34
|
+
import { createPlugin } from '{{PLUGIN_NAME}}-client';
|
|
35
|
+
|
|
36
|
+
const client = createClient('https://my-app.edgebase.fun');
|
|
37
|
+
const plugin = createPlugin(client);
|
|
38
|
+
|
|
39
|
+
// Call plugin functions — fully typed
|
|
40
|
+
const result = await plugin.doSomething({ input: 'hello' });
|
|
41
|
+
|
|
42
|
+
// Read plugin tables
|
|
43
|
+
const items = await plugin.getItems();
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Server Functions
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
// Inside another server function — inter-function calls
|
|
50
|
+
const result = await ctx.admin.functions.call('{{PLUGIN_NAME}}/hello', {
|
|
51
|
+
input: 'hello',
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Access Rules
|
|
56
|
+
|
|
57
|
+
Tables use EdgeBase access rules. Common patterns:
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
access: {
|
|
61
|
+
read: (auth, row) => auth?.id === row.userId, // Owner only
|
|
62
|
+
insert: (auth) => auth !== null, // Any authenticated user
|
|
63
|
+
update: (auth, row) => auth?.id === row.userId, // Owner only
|
|
64
|
+
delete: () => false, // Nobody
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Plugin Manifest
|
|
69
|
+
|
|
70
|
+
Put CLI-facing metadata directly in `definePlugin()`:
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
manifest: {
|
|
74
|
+
description: 'Short description shown by edgebase plugins list',
|
|
75
|
+
docsUrl: 'https://example.com/docs/{{PLUGIN_NAME}}',
|
|
76
|
+
configTemplate: {
|
|
77
|
+
apiKey: 'CHANGE_ME',
|
|
78
|
+
},
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Development
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
cd server && npm run dev # Watch mode (auto-rebuild on changes)
|
|
86
|
+
npx edgebase dev # Start local dev server
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## License
|
|
90
|
+
|
|
91
|
+
MIT
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PLUGIN_NAME}}-client",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Client SDK for {{PLUGIN_NAME}}",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsc",
|
|
10
|
+
"dev": "tsc --watch"
|
|
11
|
+
},
|
|
12
|
+
"peerDependencies": {
|
|
13
|
+
"@edge-base/web": ">=0.1.0"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@edge-base/plugin-core": "latest"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@edge-base/web": "latest",
|
|
20
|
+
"typescript": "^5.0.0"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT"
|
|
23
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* {{PLUGIN_NAME}} — JS Client SDK
|
|
3
|
+
*
|
|
4
|
+
* Typed client wrapper for {{PLUGIN_NAME}}.
|
|
5
|
+
* Uses PluginClientFactory pattern from @edge-base/plugin-core.
|
|
6
|
+
*
|
|
7
|
+
* ─── Quick Start ───
|
|
8
|
+
*
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { createClient } from '@edge-base/web';
|
|
11
|
+
* import { createPlugin } from '{{PLUGIN_NAME}}-client';
|
|
12
|
+
*
|
|
13
|
+
* const client = createClient('https://my-app.edgebase.fun');
|
|
14
|
+
* const plugin = createPlugin(client);
|
|
15
|
+
*
|
|
16
|
+
* // Call server functions
|
|
17
|
+
* const result = await plugin.doSomething({ input: 'hello' });
|
|
18
|
+
*
|
|
19
|
+
* // Read plugin tables
|
|
20
|
+
* const items = await plugin.getItems();
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
import type { PluginClientFactory, PluginClientHost } from '@edge-base/plugin-core';
|
|
24
|
+
|
|
25
|
+
const NS = '{{PLUGIN_NAME}}';
|
|
26
|
+
|
|
27
|
+
// ─── Types ───
|
|
28
|
+
|
|
29
|
+
export interface Item {
|
|
30
|
+
id: string;
|
|
31
|
+
name: string;
|
|
32
|
+
status: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// ─── Client Interface ───
|
|
36
|
+
|
|
37
|
+
export interface PluginClient {
|
|
38
|
+
/**
|
|
39
|
+
* Example function — replace with your own.
|
|
40
|
+
* Calls server function: {{PLUGIN_NAME}}/do-something
|
|
41
|
+
*/
|
|
42
|
+
doSomething(data: { input: string }): Promise<{ result: string }>;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* List items from the plugin's table.
|
|
46
|
+
* Reads from: {{PLUGIN_NAME}}/items
|
|
47
|
+
*/
|
|
48
|
+
getItems(): Promise<Item[]>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// ─── Factory ───
|
|
52
|
+
|
|
53
|
+
export const createPlugin: PluginClientFactory<PluginClient> = (
|
|
54
|
+
jb: PluginClientHost,
|
|
55
|
+
): PluginClient => ({
|
|
56
|
+
|
|
57
|
+
async doSomething(data) {
|
|
58
|
+
return (await jb.functions.call(`${NS}/do-something`, data)) as { result: string };
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
async getItems() {
|
|
62
|
+
const result = await (jb.table(`${NS}/items`) as {
|
|
63
|
+
list(opts?: Record<string, unknown>): Promise<{ items: Item[] }>;
|
|
64
|
+
}).list();
|
|
65
|
+
return result.items;
|
|
66
|
+
},
|
|
67
|
+
|
|
68
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"moduleResolution": "bundler",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"outDir": "dist",
|
|
8
|
+
"rootDir": "src",
|
|
9
|
+
"strict": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true
|
|
12
|
+
},
|
|
13
|
+
"include": ["src"]
|
|
14
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PLUGIN_NAME}}",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "EdgeBase plugin — {{PLUGIN_NAME}}",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsc",
|
|
10
|
+
"dev": "tsc --watch"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@edge-base/plugin-core": "latest"
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"typescript": "^5.0.0"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT"
|
|
19
|
+
}
|