@proappstore/cli 2.2.0 → 2.4.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/dist/create.d.ts.map +1 -1
- package/dist/create.js +82 -132
- package/dist/create.js.map +1 -1
- package/dist/domain.d.ts +3 -0
- package/dist/domain.d.ts.map +1 -0
- package/dist/domain.js +193 -0
- package/dist/domain.js.map +1 -0
- package/dist/index.js +6 -10
- package/dist/index.js.map +1 -1
- package/dist/lib/config.d.ts +23 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +54 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/github.d.ts +11 -0
- package/dist/lib/github.d.ts.map +1 -0
- package/dist/lib/github.js +60 -0
- package/dist/lib/github.js.map +1 -0
- package/dist/login.d.ts +6 -0
- package/dist/login.d.ts.map +1 -0
- package/dist/login.js +34 -0
- package/dist/login.js.map +1 -0
- package/dist/publish.d.ts.map +1 -1
- package/dist/publish.js +37 -4
- package/dist/publish.js.map +1 -1
- package/package.json +2 -1
- package/templates/icon-192.png +0 -0
- package/templates/icon-512.png +0 -0
package/dist/create.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"AAgBA,UAAU,aAAa;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAMD,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgGtF"}
|
package/dist/create.js
CHANGED
|
@@ -1,155 +1,58 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { access, readdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { writeFileSync } from 'node:fs';
|
|
4
|
+
import { extname, join, resolve } from 'node:path';
|
|
5
|
+
import { resolveToken } from './lib/config.js';
|
|
6
|
+
const TEMPLATE_REPO = 'proappstore-online/template-app';
|
|
4
7
|
const PAS_API = 'https://api.proappstore.online';
|
|
5
|
-
const
|
|
6
|
-
'
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"engines": { "node": ">=22" },
|
|
11
|
-
"repository": { "type": "git", "url": "git+https://github.com/proappstore-online/__APP_ID__.git" },
|
|
12
|
-
"scripts": {
|
|
13
|
-
"dev": "pnpm --filter @__APP_ID__/web dev",
|
|
14
|
-
"build": "pnpm --filter @__APP_ID__/web build",
|
|
15
|
-
"preview": "pnpm --filter @__APP_ID__/web preview",
|
|
16
|
-
"typecheck": "pnpm --filter @__APP_ID__/web exec tsc -b",
|
|
17
|
-
"test": "pnpm --filter @__APP_ID__/web exec tsc -b"
|
|
18
|
-
}
|
|
19
|
-
}`,
|
|
20
|
-
'pnpm-workspace.yaml': `packages:\n - web`,
|
|
21
|
-
'tsconfig.json': `{ "references": [{ "path": "./web" }], "files": [] }`,
|
|
22
|
-
'LICENSE': `MIT License\n\nCopyright (c) ${new Date().getFullYear()} ProAppStore\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.`,
|
|
23
|
-
'CLAUDE.md': `# __APP_ID__\n\n__APP_DESCRIPTION__\n\n- Subdomain: \`__APP_ID__.proappstore.online\`\n- Dev: \`pnpm install && pnpm dev\`\n- Build: \`pnpm build\`\n- Deploy: \`git push origin main\` (auto-deploys via Cloudflare Pages)\n\nFor platform conventions, read\nhttps://proappstore.online/skills.md\nbefore writing or changing anything.`,
|
|
24
|
-
'.gitignore': `node_modules/\ndist/\n.DS_Store\n*.log\n.env\n.env.local`,
|
|
25
|
-
'web/package.json': `{
|
|
26
|
-
"name": "@__APP_ID__/web",
|
|
27
|
-
"private": true,
|
|
28
|
-
"version": "0.1.0",
|
|
29
|
-
"type": "module",
|
|
30
|
-
"scripts": {
|
|
31
|
-
"dev": "vite",
|
|
32
|
-
"build": "tsc -b && vite build",
|
|
33
|
-
"preview": "vite preview"
|
|
34
|
-
},
|
|
35
|
-
"dependencies": {
|
|
36
|
-
"@proappstore/sdk": "^1.5.0",
|
|
37
|
-
"react": "^19.2.5",
|
|
38
|
-
"react-dom": "^19.2.5"
|
|
39
|
-
},
|
|
40
|
-
"devDependencies": {
|
|
41
|
-
"@tailwindcss/vite": "^4.2.4",
|
|
42
|
-
"@types/react": "^19.2.14",
|
|
43
|
-
"@types/react-dom": "^19.2.3",
|
|
44
|
-
"@vitejs/plugin-react": "^6.0.1",
|
|
45
|
-
"tailwindcss": "^4.2.4",
|
|
46
|
-
"typescript": "~6.0.2",
|
|
47
|
-
"vite": "^8.0.10"
|
|
48
|
-
}
|
|
49
|
-
}`,
|
|
50
|
-
'web/tsconfig.json': `{\n "files": [],\n "references": [\n { "path": "./tsconfig.app.json" },\n { "path": "./tsconfig.node.json" }\n ]\n}`,
|
|
51
|
-
'web/tsconfig.app.json': `{
|
|
52
|
-
"compilerOptions": {
|
|
53
|
-
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
54
|
-
"target": "es2023",
|
|
55
|
-
"lib": ["ES2023", "DOM", "DOM.Iterable"],
|
|
56
|
-
"module": "esnext",
|
|
57
|
-
"types": ["vite/client"],
|
|
58
|
-
"skipLibCheck": true,
|
|
59
|
-
"moduleResolution": "bundler",
|
|
60
|
-
"allowImportingTsExtensions": true,
|
|
61
|
-
"verbatimModuleSyntax": true,
|
|
62
|
-
"moduleDetection": "force",
|
|
63
|
-
"noEmit": true,
|
|
64
|
-
"jsx": "react-jsx",
|
|
65
|
-
"noUnusedLocals": true,
|
|
66
|
-
"noUnusedParameters": true,
|
|
67
|
-
"erasableSyntaxOnly": true,
|
|
68
|
-
"noFallthroughCasesInSwitch": true
|
|
69
|
-
},
|
|
70
|
-
"include": ["src"]
|
|
71
|
-
}`,
|
|
72
|
-
'web/tsconfig.node.json': `{
|
|
73
|
-
"compilerOptions": {
|
|
74
|
-
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
|
75
|
-
"target": "es2023",
|
|
76
|
-
"lib": ["ES2023"],
|
|
77
|
-
"module": "esnext",
|
|
78
|
-
"skipLibCheck": true,
|
|
79
|
-
"moduleResolution": "bundler",
|
|
80
|
-
"allowImportingTsExtensions": true,
|
|
81
|
-
"verbatimModuleSyntax": true,
|
|
82
|
-
"moduleDetection": "force",
|
|
83
|
-
"noEmit": true
|
|
84
|
-
},
|
|
85
|
-
"include": ["vite.config.ts"]
|
|
86
|
-
}`,
|
|
87
|
-
'web/vite.config.ts': `import { defineConfig } from 'vite'\nimport react from '@vitejs/plugin-react'\nimport tailwindcss from '@tailwindcss/vite'\n\nexport default defineConfig({\n plugins: [react(), tailwindcss()],\n server: { host: true },\n})`,
|
|
88
|
-
'web/index.html': `<!doctype html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, user-scalable=no" />\n <meta name="theme-color" content="#7c3aed" />\n <link rel="preconnect" href="https://fonts.googleapis.com" />\n <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />\n <link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,500;9..144,600;9..144,700&family=Manrope:wght@400;500;600;700;800&display=swap" rel="stylesheet" />\n <title>__APP_NAME__ — ProAppStore</title>\n </head>\n <body>\n <div id="root"></div>\n <script type="module" src="/src/main.tsx"></script>\n </body>\n</html>`,
|
|
89
|
-
'web/src/main.tsx': `import { StrictMode } from 'react'\nimport { createRoot } from 'react-dom/client'\nimport './index.css'\nimport App from './App.tsx'\n\ncreateRoot(document.getElementById('root')!).render(\n <StrictMode>\n <App />\n </StrictMode>,\n)`,
|
|
90
|
-
'web/src/index.css': `@import "tailwindcss";\n\n@layer base {\n:root {\n color-scheme: light;\n --paper: #ffffff;\n --ink: #111111;\n --muted: #666666;\n --accent: #7c3aed;\n --accent-soft: #f5f3ff;\n --line: rgba(0,0,0,0.08);\n --glass: rgba(255,255,255,0.72);\n --glass-hover: rgba(255,255,255,0.85);\n --error: #c74f43;\n --success: #2f8f57;\n}\n\n:root[data-theme='dark'] {\n color-scheme: dark;\n --paper: #000000;\n --ink: #f0f0f0;\n --muted: #888888;\n --accent: #a78bfa;\n --accent-soft: #1e1533;\n --line: rgba(255,255,255,0.08);\n --glass: rgba(26,26,26,0.8);\n --glass-hover: rgba(38,38,38,0.9);\n --error: #ff7a72;\n --success: #74d49a;\n}\n\nhtml { min-height: 100%; }\nbody {\n min-height: 100dvh;\n background: var(--paper);\n color: var(--ink);\n font-family: 'Manrope', -apple-system, sans-serif;\n -webkit-font-smoothing: antialiased;\n}\n#root { min-height: 100dvh; }\n.display-font { font-family: 'Fraunces', Georgia, serif; letter-spacing: -0.04em; }\n} /* end @layer base */`,
|
|
91
|
-
'web/src/App.tsx': `import { initPro } from '@proappstore/sdk'\nimport { useProGate } from '@proappstore/sdk/hooks'\n\nconst app = initPro({ appId: '__APP_ID__' })\n\nexport default function App() {\n const { gate, user, signIn, upgrade } = useProGate(app, { allowFree: true })\n\n if (gate === 'loading') {\n return (\n <div className="flex min-h-[100dvh] items-center justify-center">\n <p className="text-[var(--muted)]">Loading...</p>\n </div>\n )\n }\n\n if (gate === 'signed-out') {\n return (\n <div className="flex min-h-[100dvh] flex-col items-center justify-center gap-4 px-4">\n <h1 className="display-font text-3xl font-bold text-[var(--ink)]">__APP_NAME__</h1>\n <p className="text-[var(--muted)]">Sign in to get started.</p>\n <button onClick={signIn} className="rounded-2xl bg-[var(--accent)] px-6 py-2.5 text-sm font-semibold text-white">Sign in with GitHub</button>\n </div>\n )\n }\n\n return (\n <div className="mx-auto max-w-2xl px-4 py-8">\n <h1 className="display-font text-2xl font-bold text-[var(--ink)]">__APP_NAME__</h1>\n <p className="mt-2 text-[var(--muted)]">Welcome, {user?.login}! Edit web/src/App.tsx to start building.</p>\n </div>\n )\n}`,
|
|
92
|
-
};
|
|
8
|
+
const TEXT_EXTENSIONS = new Set([
|
|
9
|
+
'.md', '.txt', '.json', '.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs',
|
|
10
|
+
'.html', '.htm', '.css', '.scss', '.yaml', '.yml', '.toml', '.svg',
|
|
11
|
+
]);
|
|
12
|
+
const SKIP_DIRS = new Set(['.git', 'node_modules', 'dist', '.cache']);
|
|
93
13
|
function toTitleCase(id) {
|
|
94
14
|
return id.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ');
|
|
95
15
|
}
|
|
96
16
|
export async function createApp(appId, opts = {}) {
|
|
97
|
-
// Validate app ID
|
|
98
17
|
if (!/^[a-z][a-z0-9-]*$/.test(appId) || appId.length > 58) {
|
|
99
18
|
process.stderr.write(`Invalid app ID "${appId}". Use lowercase letters, numbers, hyphens. Max 58 chars.\n`);
|
|
100
19
|
process.exit(1);
|
|
101
20
|
}
|
|
102
21
|
const targetDir = resolve(appId);
|
|
103
|
-
if (
|
|
22
|
+
if (await exists(targetDir)) {
|
|
104
23
|
process.stderr.write(`Directory "${appId}" already exists.\n`);
|
|
105
24
|
process.exit(1);
|
|
106
25
|
}
|
|
107
26
|
const appName = toTitleCase(appId);
|
|
108
27
|
process.stdout.write(`\n Creating ${appName}...\n\n`);
|
|
109
|
-
// Step 1:
|
|
110
|
-
process.stdout.write(` [1/
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
.replace(/__APP_NAME__/g, appName)
|
|
118
|
-
.replace(/__APP_DESCRIPTION__/g, `A pro app on ProAppStore.`);
|
|
119
|
-
writeFileSync(fullPath, processed);
|
|
120
|
-
}
|
|
121
|
-
// Step 2: Install
|
|
28
|
+
// Step 1: Clone template
|
|
29
|
+
process.stdout.write(` [1/4] Cloning template...\n`);
|
|
30
|
+
await run('git', ['clone', '--depth=1', `https://github.com/${TEMPLATE_REPO}.git`, targetDir]);
|
|
31
|
+
await rm(join(targetDir, '.git'), { recursive: true, force: true });
|
|
32
|
+
// Step 2: Replace APPNAME placeholders
|
|
33
|
+
process.stdout.write(` [2/4] Configuring for ${appId}...\n`);
|
|
34
|
+
const substitutionCount = await substituteAppName(targetDir, appId, appName);
|
|
35
|
+
// Step 3: Install
|
|
122
36
|
if (!opts.skipInstall) {
|
|
123
|
-
process.stdout.write(` [
|
|
37
|
+
process.stdout.write(` [3/4] Installing dependencies...\n`);
|
|
124
38
|
try {
|
|
125
|
-
|
|
39
|
+
await run('pnpm', ['install'], targetDir);
|
|
126
40
|
}
|
|
127
41
|
catch {
|
|
128
|
-
process.stdout.write(` [
|
|
42
|
+
process.stdout.write(` [3/4] pnpm install failed. Run it manually.\n`);
|
|
129
43
|
}
|
|
130
44
|
}
|
|
131
45
|
else {
|
|
132
|
-
process.stdout.write(` [
|
|
46
|
+
process.stdout.write(` [3/4] Skipping install (--skip-install)\n`);
|
|
133
47
|
}
|
|
134
|
-
// Step
|
|
48
|
+
// Step 4: Init git + provision
|
|
135
49
|
if (!opts.skipGit) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
cwd: targetDir,
|
|
140
|
-
stdio: 'pipe',
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
catch {
|
|
144
|
-
process.stdout.write(` [3/3] Git init failed. Run it manually.\n`);
|
|
145
|
-
}
|
|
50
|
+
await run('git', ['init', '-q', '-b', 'main'], targetDir);
|
|
51
|
+
await run('git', ['add', '-A'], targetDir);
|
|
52
|
+
await run('git', ['commit', '-q', '-m', 'Initial commit from pas create'], targetDir);
|
|
146
53
|
}
|
|
147
|
-
else {
|
|
148
|
-
process.stdout.write(` [3/3] Skipping git init (--skip-git)\n`);
|
|
149
|
-
}
|
|
150
|
-
// Step 4: Provision platform resources (D1 + Data Worker)
|
|
151
54
|
if (!opts.skipProvision) {
|
|
152
|
-
const token = opts.token
|
|
55
|
+
const token = resolveToken(opts.token);
|
|
153
56
|
if (token) {
|
|
154
57
|
process.stdout.write(` [4/4] Provisioning platform resources...\n`);
|
|
155
58
|
try {
|
|
@@ -160,6 +63,8 @@ export async function createApp(appId, opts = {}) {
|
|
|
160
63
|
appId,
|
|
161
64
|
name: appName,
|
|
162
65
|
description: `${appName} — pro app on ProAppStore.`,
|
|
66
|
+
skipCompliance: true,
|
|
67
|
+
skipPublish: true,
|
|
163
68
|
}),
|
|
164
69
|
});
|
|
165
70
|
const data = (await res.json());
|
|
@@ -167,7 +72,6 @@ export async function createApp(appId, opts = {}) {
|
|
|
167
72
|
const icon = step.status === 'ok' ? '+' : step.status === 'skip' ? '-' : '!';
|
|
168
73
|
process.stdout.write(` [${icon}] ${step.name}: ${step.detail}\n`);
|
|
169
74
|
}
|
|
170
|
-
// Write the Data Worker URL into the app's config
|
|
171
75
|
const dbStep = data.steps.find(s => s.name === 'create_d1' && s.status === 'ok');
|
|
172
76
|
if (dbStep) {
|
|
173
77
|
const configPath = join(targetDir, '.pas.json');
|
|
@@ -184,23 +88,69 @@ export async function createApp(appId, opts = {}) {
|
|
|
184
88
|
}
|
|
185
89
|
}
|
|
186
90
|
else {
|
|
187
|
-
process.stdout.write(` [4/4] Skipping provision (no auth token).
|
|
91
|
+
process.stdout.write(` [4/4] Skipping provision (no auth token). Run \`pas login\`, set PAS_SESSION_TOKEN, or use --token.\n`);
|
|
188
92
|
}
|
|
189
93
|
}
|
|
190
94
|
else {
|
|
191
95
|
process.stdout.write(` [4/4] Skipping provision (--skip-provision)\n`);
|
|
192
96
|
}
|
|
193
97
|
process.stdout.write(`
|
|
194
|
-
Done!
|
|
98
|
+
Done! Replaced APPNAME in ${substitutionCount} files.
|
|
195
99
|
|
|
196
100
|
Next steps:
|
|
197
101
|
cd ${appId}
|
|
198
102
|
pnpm dev
|
|
199
103
|
|
|
200
|
-
|
|
201
|
-
Console:
|
|
202
|
-
Dashboard: https://dashboard.proappstore.online
|
|
104
|
+
Docs: https://proappstore.online/docs
|
|
105
|
+
Console: https://console.proappstore.online
|
|
203
106
|
|
|
204
107
|
`);
|
|
205
108
|
}
|
|
109
|
+
async function substituteAppName(dir, appId, appName) {
|
|
110
|
+
let count = 0;
|
|
111
|
+
for await (const file of walk(dir)) {
|
|
112
|
+
if (!TEXT_EXTENSIONS.has(extname(file).toLowerCase()))
|
|
113
|
+
continue;
|
|
114
|
+
const content = await readFile(file, 'utf8');
|
|
115
|
+
if (!content.includes('APPNAME'))
|
|
116
|
+
continue;
|
|
117
|
+
await writeFile(file, content.split('APPNAME').join(appId));
|
|
118
|
+
count++;
|
|
119
|
+
}
|
|
120
|
+
return count;
|
|
121
|
+
}
|
|
122
|
+
async function* walk(dir) {
|
|
123
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
124
|
+
for (const entry of entries) {
|
|
125
|
+
if (entry.isDirectory()) {
|
|
126
|
+
if (SKIP_DIRS.has(entry.name))
|
|
127
|
+
continue;
|
|
128
|
+
yield* walk(join(dir, entry.name));
|
|
129
|
+
}
|
|
130
|
+
else if (entry.isFile()) {
|
|
131
|
+
yield join(dir, entry.name);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
async function exists(path) {
|
|
136
|
+
try {
|
|
137
|
+
await access(path);
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function run(cmd, args, cwd) {
|
|
145
|
+
return new Promise((resolveFn, rejectFn) => {
|
|
146
|
+
const child = spawn(cmd, args, { stdio: 'inherit', cwd });
|
|
147
|
+
child.on('exit', (code) => {
|
|
148
|
+
if (code === 0)
|
|
149
|
+
resolveFn();
|
|
150
|
+
else
|
|
151
|
+
rejectFn(new Error(`${cmd} exited with code ${code}`));
|
|
152
|
+
});
|
|
153
|
+
child.on('error', rejectFn);
|
|
154
|
+
});
|
|
155
|
+
}
|
|
206
156
|
//# sourceMappingURL=create.js.map
|
package/dist/create.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.js","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"create.js","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,aAAa,GAAG,iCAAiC,CAAC;AACxD,MAAM,OAAO,GAAG,gCAAgC,CAAC;AAEjD,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC9B,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IACpE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CACnE,CAAC,CAAC;AAEH,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AAStE,SAAS,WAAW,CAAC,EAAU;IAC7B,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,KAAa,EAAE,OAAsB,EAAE;IACrE,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QAC1D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,KAAK,6DAA6D,CAAC,CAAC;QAC5G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IACjC,IAAI,MAAM,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,KAAK,qBAAqB,CAAC,CAAC;QAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,OAAO,SAAS,CAAC,CAAC;IAEvD,yBAAyB;IACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACtD,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,sBAAsB,aAAa,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAC/F,MAAM,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAEpE,uCAAuC;IACvC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,KAAK,OAAO,CAAC,CAAC;IAC9D,MAAM,iBAAiB,GAAG,MAAM,iBAAiB,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAE7E,kBAAkB;IAClB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;QACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC7D,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACtE,CAAC;IAED,+BAA+B;IAC/B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC;QAC1D,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;QAC3C,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,gCAAgC,CAAC,EAAE,SAAS,CAAC,CAAC;IACxF,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;YACrE,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,eAAe,EAAE;oBACjD,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;oBACjF,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;wBACnB,KAAK;wBACL,IAAI,EAAE,OAAO;wBACb,WAAW,EAAE,GAAG,OAAO,4BAA4B;wBACnD,cAAc,EAAE,IAAI;wBACpB,WAAW,EAAE,IAAI;qBAClB,CAAC;iBACH,CAAC,CAAC;gBACH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAiF,CAAC;gBAChH,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;oBAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;oBAC7E,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;gBACvE,CAAC;gBAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC;gBACjF,IAAI,MAAM,EAAE,CAAC;oBACX,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;oBAChD,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC;wBACvC,KAAK;wBACL,WAAW,EAAE,oBAAoB,KAAK,4BAA4B;wBAClE,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE;qBAC5D,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;oBACb,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;gBAC5D,CAAC;YACH,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,8BAA8B,CAAC,CAAC;YACpF,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yGAAyG,CAAC,CAAC;QAClI,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;8BACO,iBAAiB;;;SAGtC,KAAK;;;;;;CAMb,CAAC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,GAAW,EAAE,KAAa,EAAE,OAAe;IAC1E,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YAAE,SAAS;QAChE,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,SAAS;QAC3C,MAAM,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5D,KAAK,EAAE,CAAC;IACV,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,GAAW;IAC9B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,SAAS;YACxC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QACrC,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;AACH,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,IAAY;IAChC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,GAAG,CAAC,GAAW,EAAE,IAAc,EAAE,GAAY;IACpD,OAAO,IAAI,OAAO,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE;QACzC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;QAC1D,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACxB,IAAI,IAAI,KAAK,CAAC;gBAAE,SAAS,EAAE,CAAC;;gBACvB,QAAQ,CAAC,IAAI,KAAK,CAAC,GAAG,GAAG,qBAAqB,IAAI,EAAE,CAAC,CAAC,CAAC;QAC9D,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/domain.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../src/domain.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA0NpC,eAAO,MAAM,aAAa,SAA8E,CAAC"}
|
package/dist/domain.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { resolveToken } from './lib/config.js';
|
|
5
|
+
const PAS_API = 'https://api.proappstore.online';
|
|
6
|
+
const isTTY = Boolean(process.stdout.isTTY) && process.env.NO_COLOR !== '1';
|
|
7
|
+
const ansi = (open) => (s) => (isTTY ? `\x1b[${open}m${s}\x1b[39m` : s);
|
|
8
|
+
const green = ansi('32');
|
|
9
|
+
const yellow = ansi('33');
|
|
10
|
+
const red = ansi('31');
|
|
11
|
+
const dim = (s) => (isTTY ? `\x1b[2m${s}\x1b[22m` : s);
|
|
12
|
+
const bold = (s) => (isTTY ? `\x1b[1m${s}\x1b[22m` : s);
|
|
13
|
+
function readJsonIfExists(path) {
|
|
14
|
+
if (!existsSync(path))
|
|
15
|
+
return null;
|
|
16
|
+
try {
|
|
17
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function getAppId() {
|
|
24
|
+
const pkg = readJsonIfExists(resolve(process.cwd(), 'package.json'));
|
|
25
|
+
if (!pkg?.name) {
|
|
26
|
+
process.stderr.write('pas domain: no package.json with a `name` field in the current directory.\n' +
|
|
27
|
+
'Run this from the root of a pas-scaffolded app.\n');
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
if (!/^[a-z][a-z0-9-]*$/.test(pkg.name) || pkg.name.length > 58) {
|
|
31
|
+
process.stderr.write(`pas domain: package.json name "${pkg.name}" is not a valid app id.\n`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
return pkg.name;
|
|
35
|
+
}
|
|
36
|
+
function getToken(opts) {
|
|
37
|
+
const token = resolveToken(opts.token);
|
|
38
|
+
if (!token) {
|
|
39
|
+
process.stderr.write('pas domain: no auth token. Run `pas login` first, or use --token.\n');
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
return token;
|
|
43
|
+
}
|
|
44
|
+
async function api(method, path, token, body) {
|
|
45
|
+
const init = {
|
|
46
|
+
method,
|
|
47
|
+
headers: {
|
|
48
|
+
Authorization: `Bearer ${token}`,
|
|
49
|
+
...(body ? { 'Content-Type': 'application/json' } : {}),
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
if (body !== undefined)
|
|
53
|
+
init.body = JSON.stringify(body);
|
|
54
|
+
const res = await fetch(`${PAS_API}${path}`, init);
|
|
55
|
+
let data = null;
|
|
56
|
+
try {
|
|
57
|
+
data = await res.json();
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
data = { error: await res.text().catch(() => '') };
|
|
61
|
+
}
|
|
62
|
+
return { status: res.status, data };
|
|
63
|
+
}
|
|
64
|
+
function statusBadge(status) {
|
|
65
|
+
if (status === 'active')
|
|
66
|
+
return green('● active');
|
|
67
|
+
if (status === 'pending')
|
|
68
|
+
return yellow('● pending DNS');
|
|
69
|
+
return red('● failed');
|
|
70
|
+
}
|
|
71
|
+
function renderDomain(d, appId) {
|
|
72
|
+
process.stdout.write(`\n ${bold(d.domain)} ${statusBadge(d.status)}\n`);
|
|
73
|
+
if (d.cfStatus)
|
|
74
|
+
process.stdout.write(` ${dim(`CF: ${d.cfStatus}`)}\n`);
|
|
75
|
+
if (d.status === 'active') {
|
|
76
|
+
process.stdout.write(` ${dim(`verified ${new Date(d.verifiedAt || d.addedAt).toLocaleString()}`)}\n`);
|
|
77
|
+
process.stdout.write(` Live at: https://${d.domain}\n`);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
// Status is cached at the time it was last attached or verified. PAS does
|
|
81
|
+
// no background polling — the owner triggers a fresh check by running
|
|
82
|
+
// `pas domain verify <domain>`. Make that contract explicit here so the
|
|
83
|
+
// owner isn't surprised when nothing changes between `pas domain list`
|
|
84
|
+
// invocations.
|
|
85
|
+
process.stdout.write(` ${dim(`status as of ${new Date(d.addedAt).toLocaleString()} — run \`pas domain verify ${d.domain}\` to refresh`)}\n`);
|
|
86
|
+
const vd = d.verificationData || {};
|
|
87
|
+
const valid = d.validationData || {};
|
|
88
|
+
process.stdout.write(`\n ${bold('Add this DNS record at your registrar:')}\n\n`);
|
|
89
|
+
process.stdout.write(` Type: CNAME\n`);
|
|
90
|
+
process.stdout.write(` Name: ${d.domain}\n`);
|
|
91
|
+
process.stdout.write(` Value: ${bold(`proappstore-${appId}.pages.dev`)}\n`);
|
|
92
|
+
process.stdout.write(`\n ${dim('Apex domains (e.g. example.com without a subdomain) can\'t use a raw CNAME')}\n` +
|
|
93
|
+
` ${dim('per RFC. Use ALIAS/ANAME if your registrar supports it, or set A/AAAA')}\n` +
|
|
94
|
+
` ${dim('records pointing to Cloudflare anycast IPs (CF will tell you which).')}\n`);
|
|
95
|
+
// CF only emits TXT validation when HTTP-01 isn't possible — usually
|
|
96
|
+
// because DNS isn't yet pointing correctly. When method is 'txt', the
|
|
97
|
+
// owner needs this record too.
|
|
98
|
+
if (valid.method === 'txt' && valid.txt_name && valid.txt_value) {
|
|
99
|
+
process.stdout.write(`\n ${dim('Plus this TXT record for SSL validation:')}\n`);
|
|
100
|
+
process.stdout.write(` Type: TXT\n`);
|
|
101
|
+
process.stdout.write(` Name: ${valid.txt_name}\n`);
|
|
102
|
+
process.stdout.write(` Value: ${valid.txt_value}\n`);
|
|
103
|
+
}
|
|
104
|
+
if (vd.error_message) {
|
|
105
|
+
process.stdout.write(`\n ${red('Last verification error:')} ${vd.error_message}\n`);
|
|
106
|
+
}
|
|
107
|
+
else if (valid.error_message) {
|
|
108
|
+
process.stdout.write(`\n ${red('Last validation error:')} ${valid.error_message}\n`);
|
|
109
|
+
}
|
|
110
|
+
process.stdout.write(`\n After adding the records, run: ${bold(`pas domain verify ${d.domain}`)}\n`);
|
|
111
|
+
}
|
|
112
|
+
async function addDomain(domain, opts) {
|
|
113
|
+
const appId = getAppId();
|
|
114
|
+
const token = getToken(opts);
|
|
115
|
+
process.stdout.write(`\n Attaching ${bold(domain)} to ${appId}...\n`);
|
|
116
|
+
const { status, data } = await api('POST', `/v1/apps/${appId}/domains`, token, { domain });
|
|
117
|
+
if (status !== 201) {
|
|
118
|
+
process.stderr.write(`\n ${red('Failed')} (${status}): ${data?.error || JSON.stringify(data)}\n\n`);
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
renderDomain(data.domain, appId);
|
|
122
|
+
process.stdout.write('\n');
|
|
123
|
+
}
|
|
124
|
+
async function listCmd(opts) {
|
|
125
|
+
const appId = getAppId();
|
|
126
|
+
const token = getToken(opts);
|
|
127
|
+
const { status, data } = await api('GET', `/v1/apps/${appId}/domains`, token);
|
|
128
|
+
if (status !== 200) {
|
|
129
|
+
process.stderr.write(` pas domain list failed (${status}): ${data?.error || JSON.stringify(data)}\n`);
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
const domains = data.domains || [];
|
|
133
|
+
if (domains.length === 0) {
|
|
134
|
+
process.stdout.write(`\n No custom domains attached to ${appId}.\n`);
|
|
135
|
+
process.stdout.write(` Add one with: ${bold('pas domain add example.com')}\n\n`);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
for (const d of domains)
|
|
139
|
+
renderDomain(d, appId);
|
|
140
|
+
process.stdout.write('\n');
|
|
141
|
+
}
|
|
142
|
+
async function verifyCmd(domain, opts) {
|
|
143
|
+
const appId = getAppId();
|
|
144
|
+
const token = getToken(opts);
|
|
145
|
+
process.stdout.write(`\n Re-checking ${bold(domain)}...\n`);
|
|
146
|
+
const { status, data } = await api('POST', `/v1/apps/${appId}/domains/${encodeURIComponent(domain)}/verify`, token);
|
|
147
|
+
if (status !== 200) {
|
|
148
|
+
process.stderr.write(` ${red('Verify failed')} (${status}): ${data?.error || JSON.stringify(data)}\n`);
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
renderDomain(data.domain, appId);
|
|
152
|
+
process.stdout.write('\n');
|
|
153
|
+
}
|
|
154
|
+
async function removeCmd(domain, opts) {
|
|
155
|
+
const appId = getAppId();
|
|
156
|
+
const token = getToken(opts);
|
|
157
|
+
if (!opts.yes) {
|
|
158
|
+
process.stderr.write(`\n Detach ${bold(domain)} from ${appId}? This will stop serving the app at this domain.\n` +
|
|
159
|
+
` Re-run with --yes to confirm.\n\n`);
|
|
160
|
+
process.exit(2);
|
|
161
|
+
}
|
|
162
|
+
const { status, data } = await api('DELETE', `/v1/apps/${appId}/domains/${encodeURIComponent(domain)}`, token);
|
|
163
|
+
if (status !== 200) {
|
|
164
|
+
process.stderr.write(` ${red('Remove failed')} (${status}): ${data?.error || JSON.stringify(data)}\n`);
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
process.stdout.write(`\n ${green('Detached')} ${domain}.\n\n`);
|
|
168
|
+
}
|
|
169
|
+
export const domainCommand = new Command('domain').description('Manage BYO custom domains for this app');
|
|
170
|
+
domainCommand
|
|
171
|
+
.command('add <domain>')
|
|
172
|
+
.description('Attach a custom domain (apex or subdomain) to the current app')
|
|
173
|
+
.option('--token <token>', 'Session token (or set PAS_SESSION_TOKEN)')
|
|
174
|
+
.action(addDomain);
|
|
175
|
+
domainCommand
|
|
176
|
+
.command('list')
|
|
177
|
+
.alias('ls')
|
|
178
|
+
.description('List custom domains attached to the current app + their verification state')
|
|
179
|
+
.option('--token <token>', 'Session token (or set PAS_SESSION_TOKEN)')
|
|
180
|
+
.action(listCmd);
|
|
181
|
+
domainCommand
|
|
182
|
+
.command('verify <domain>')
|
|
183
|
+
.description('Ask Cloudflare to re-check DNS / cert for a pending domain')
|
|
184
|
+
.option('--token <token>', 'Session token (or set PAS_SESSION_TOKEN)')
|
|
185
|
+
.action(verifyCmd);
|
|
186
|
+
domainCommand
|
|
187
|
+
.command('remove <domain>')
|
|
188
|
+
.alias('rm')
|
|
189
|
+
.description('Detach a custom domain from the current app')
|
|
190
|
+
.option('--token <token>', 'Session token (or set PAS_SESSION_TOKEN)')
|
|
191
|
+
.option('--yes', 'Skip the confirmation prompt')
|
|
192
|
+
.action(removeCmd);
|
|
193
|
+
//# sourceMappingURL=domain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain.js","sourceRoot":"","sources":["../src/domain.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import { checkCommand } from './check.js';
|
|
4
4
|
import { createApp } from './create.js';
|
|
5
|
+
import { domainCommand } from './domain.js';
|
|
6
|
+
import { loginCommand } from './login.js';
|
|
5
7
|
import { publishApp } from './publish.js';
|
|
6
8
|
const program = new Command();
|
|
7
9
|
program
|
|
@@ -14,18 +16,11 @@ program
|
|
|
14
16
|
.option('--skip-install', 'Skip pnpm install')
|
|
15
17
|
.option('--skip-git', 'Skip git init')
|
|
16
18
|
.option('--skip-provision', 'Skip D1 + platform provisioning')
|
|
17
|
-
.option('--token <token>', '
|
|
19
|
+
.option('--token <token>', 'Session token (or set PAS_SESSION_TOKEN env var)')
|
|
18
20
|
.action(async (appId, opts) => {
|
|
19
21
|
await createApp(appId, opts);
|
|
20
22
|
});
|
|
21
|
-
program
|
|
22
|
-
.command('login')
|
|
23
|
-
.description('Sign in with GitHub (shared identity with `fas`).')
|
|
24
|
-
.action(() => {
|
|
25
|
-
process.stdout.write('pas login is not yet implemented.\n' +
|
|
26
|
-
'For now: run `fas login` (from @freeappstore/cli) — pro shares the same identity.\n');
|
|
27
|
-
process.exit(2);
|
|
28
|
-
});
|
|
23
|
+
program.addCommand(loginCommand);
|
|
29
24
|
program
|
|
30
25
|
.command('publish')
|
|
31
26
|
.description('Publish the current repo to ProAppStore: GitHub repo, CF Pages, DNS, D1 database, registry entry.')
|
|
@@ -35,11 +30,12 @@ program
|
|
|
35
30
|
.option('--icon <icon>', 'Icon HTML entity, e.g. "📅"')
|
|
36
31
|
.option('--icon-bg <color>', 'Icon background hex color')
|
|
37
32
|
.option('--pro-features <list>', 'Comma-separated list of features the pro subscription unlocks')
|
|
38
|
-
.option('--token <token>', '
|
|
33
|
+
.option('--token <token>', 'Session token (or set PAS_SESSION_TOKEN env var)')
|
|
39
34
|
.action(async (opts) => {
|
|
40
35
|
await publishApp(opts);
|
|
41
36
|
});
|
|
42
37
|
program.addCommand(checkCommand);
|
|
38
|
+
program.addCommand(domainCommand);
|
|
43
39
|
program.parseAsync().catch((err) => {
|
|
44
40
|
const msg = err instanceof Error ? err.message : String(err);
|
|
45
41
|
process.stderr.write(`pas: ${msg}\n`);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,KAAK,CAAC;KACX,WAAW,CAAC,0DAA0D,CAAC;KACvE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,iBAAiB,CAAC;KAC1B,WAAW,CAAC,4FAA4F,CAAC;KACzG,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC;KAC7C,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC;KACrC,MAAM,CAAC,kBAAkB,EAAE,iCAAiC,CAAC;KAC7D,MAAM,CAAC,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,KAAK,CAAC;KACX,WAAW,CAAC,0DAA0D,CAAC;KACvE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,iBAAiB,CAAC;KAC1B,WAAW,CAAC,4FAA4F,CAAC;KACzG,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC;KAC7C,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC;KACrC,MAAM,CAAC,kBAAkB,EAAE,iCAAiC,CAAC;KAC7D,MAAM,CAAC,iBAAiB,EAAE,kDAAkD,CAAC;KAC7E,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,IAA2F,EAAE,EAAE;IAC3H,MAAM,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAC/B,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AAEjC,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,mGAAmG,CAAC;KAChH,MAAM,CAAC,eAAe,EAAE,4DAA4D,CAAC;KACrF,MAAM,CAAC,uBAAuB,EAAE,iDAAiD,CAAC;KAClF,MAAM,CAAC,6BAA6B,EAAE,8CAA8C,CAAC;KACrF,MAAM,CAAC,eAAe,EAAE,oCAAoC,CAAC;KAC7D,MAAM,CAAC,mBAAmB,EAAE,2BAA2B,CAAC;KACxD,MAAM,CAAC,uBAAuB,EAAE,+DAA+D,CAAC;KAChG,MAAM,CAAC,iBAAiB,EAAE,kDAAkD,CAAC;KAC7E,MAAM,CAAC,KAAK,EAAE,IAAsI,EAAE,EAAE;IACvJ,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;AAElC,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC1C,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface CliConfig {
|
|
2
|
+
apiBase: string;
|
|
3
|
+
authApiBase: string;
|
|
4
|
+
github?: {
|
|
5
|
+
accessToken: string;
|
|
6
|
+
login: string;
|
|
7
|
+
obtainedAt: number;
|
|
8
|
+
};
|
|
9
|
+
session?: {
|
|
10
|
+
token: string;
|
|
11
|
+
obtainedAt: number;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export declare function readConfig(): Promise<CliConfig>;
|
|
15
|
+
export declare function writeConfig(config: CliConfig): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Get a session token from (in priority order):
|
|
18
|
+
* 1. --token CLI flag
|
|
19
|
+
* 2. PAS_SESSION_TOKEN env var
|
|
20
|
+
* 3. ~/.proappstore/config.json session
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveToken(cliToken?: string): string | null;
|
|
23
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,OAAO,CAAC,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAWD,wBAAsB,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,CAarD;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAIlE;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS7D"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { chmod, mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
const CONFIG_DIR = join(homedir(), '.proappstore');
|
|
6
|
+
const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
|
|
7
|
+
const DEFAULT_CONFIG = {
|
|
8
|
+
apiBase: process.env.PAS_API_BASE ?? 'https://api.proappstore.online',
|
|
9
|
+
authApiBase: process.env.PAS_AUTH_API_BASE ?? 'https://api.freeappstore.online',
|
|
10
|
+
};
|
|
11
|
+
function normalizeApiBase(s) {
|
|
12
|
+
return s.replace(/\/+$/, '');
|
|
13
|
+
}
|
|
14
|
+
export async function readConfig() {
|
|
15
|
+
try {
|
|
16
|
+
const raw = await readFile(CONFIG_FILE, 'utf8');
|
|
17
|
+
const parsed = JSON.parse(raw);
|
|
18
|
+
const merged = { ...DEFAULT_CONFIG, ...parsed };
|
|
19
|
+
return {
|
|
20
|
+
...merged,
|
|
21
|
+
apiBase: normalizeApiBase(merged.apiBase),
|
|
22
|
+
authApiBase: normalizeApiBase(merged.authApiBase),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return { ...DEFAULT_CONFIG };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export async function writeConfig(config) {
|
|
30
|
+
await mkdir(CONFIG_DIR, { recursive: true, mode: 0o700 });
|
|
31
|
+
await writeFile(CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
32
|
+
await chmod(CONFIG_FILE, 0o600);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get a session token from (in priority order):
|
|
36
|
+
* 1. --token CLI flag
|
|
37
|
+
* 2. PAS_SESSION_TOKEN env var
|
|
38
|
+
* 3. ~/.proappstore/config.json session
|
|
39
|
+
*/
|
|
40
|
+
export function resolveToken(cliToken) {
|
|
41
|
+
if (cliToken)
|
|
42
|
+
return cliToken;
|
|
43
|
+
if (process.env.PAS_SESSION_TOKEN)
|
|
44
|
+
return process.env.PAS_SESSION_TOKEN;
|
|
45
|
+
try {
|
|
46
|
+
const raw = readFileSync(CONFIG_FILE, 'utf8');
|
|
47
|
+
const config = JSON.parse(raw);
|
|
48
|
+
if (config.session?.token)
|
|
49
|
+
return config.session.token;
|
|
50
|
+
}
|
|
51
|
+
catch { }
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,cAAc,CAAC,CAAC;AACnD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAgBpD,MAAM,cAAc,GAAc;IAChC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,gCAAgC;IACrE,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,iCAAiC;CAChF,CAAC;AAEF,SAAS,gBAAgB,CAAC,CAAS;IACjC,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAuB,CAAC;QACrD,MAAM,MAAM,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;QAChD,OAAO;YACL,GAAG,MAAM;YACT,OAAO,EAAE,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC;YACzC,WAAW,EAAE,gBAAgB,CAAC,MAAM,CAAC,WAAW,CAAC;SAClD,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAiB;IACjD,MAAM,KAAK,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1D,MAAM,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/E,MAAM,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,QAAiB;IAC5C,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IACxE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC;QAC5C,IAAI,MAAM,CAAC,OAAO,EAAE,KAAK;YAAE,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface DeviceFlowStart {
|
|
2
|
+
userCode: string;
|
|
3
|
+
verificationUri: string;
|
|
4
|
+
expiresAt: number;
|
|
5
|
+
poll: () => Promise<{
|
|
6
|
+
accessToken: string;
|
|
7
|
+
login: string;
|
|
8
|
+
}>;
|
|
9
|
+
}
|
|
10
|
+
export declare function startDeviceFlow(clientId: string): Promise<DeviceFlowStart>;
|
|
11
|
+
//# sourceMappingURL=github.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/lib/github.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7D;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CA6ChF"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// GitHub Device Authorization Grant flow.
|
|
2
|
+
// Spec: https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps#device-flow
|
|
3
|
+
export async function startDeviceFlow(clientId) {
|
|
4
|
+
const codeRes = await fetch('https://github.com/login/device/code', {
|
|
5
|
+
method: 'POST',
|
|
6
|
+
headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
|
|
7
|
+
body: JSON.stringify({ client_id: clientId, scope: 'read:user' }),
|
|
8
|
+
});
|
|
9
|
+
if (!codeRes.ok) {
|
|
10
|
+
throw new Error(`GitHub device-code request failed: ${codeRes.status}`);
|
|
11
|
+
}
|
|
12
|
+
const code = (await codeRes.json());
|
|
13
|
+
let interval = code.interval;
|
|
14
|
+
const expiresAt = Date.now() + code.expires_in * 1000;
|
|
15
|
+
return {
|
|
16
|
+
userCode: code.user_code,
|
|
17
|
+
verificationUri: code.verification_uri,
|
|
18
|
+
expiresAt,
|
|
19
|
+
poll: async () => {
|
|
20
|
+
while (Date.now() < expiresAt) {
|
|
21
|
+
await sleep(interval * 1000);
|
|
22
|
+
const tokenRes = await fetch('https://github.com/login/oauth/access_token', {
|
|
23
|
+
method: 'POST',
|
|
24
|
+
headers: { Accept: 'application/json', 'Content-Type': 'application/json' },
|
|
25
|
+
body: JSON.stringify({
|
|
26
|
+
client_id: clientId,
|
|
27
|
+
device_code: code.device_code,
|
|
28
|
+
grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
|
|
29
|
+
}),
|
|
30
|
+
});
|
|
31
|
+
const token = (await tokenRes.json());
|
|
32
|
+
if (token.access_token) {
|
|
33
|
+
const login = await fetchLogin(token.access_token);
|
|
34
|
+
return { accessToken: token.access_token, login };
|
|
35
|
+
}
|
|
36
|
+
if (token.error === 'slow_down') {
|
|
37
|
+
interval = token.interval ?? interval + 5;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (token.error === 'authorization_pending')
|
|
41
|
+
continue;
|
|
42
|
+
throw new Error(`GitHub authorization failed: ${token.error ?? 'unknown'}`);
|
|
43
|
+
}
|
|
44
|
+
throw new Error('Device code expired before authorization completed.');
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
async function fetchLogin(token) {
|
|
49
|
+
const res = await fetch('https://api.github.com/user', {
|
|
50
|
+
headers: { Authorization: `Bearer ${token}`, Accept: 'application/vnd.github+json' },
|
|
51
|
+
});
|
|
52
|
+
if (!res.ok)
|
|
53
|
+
throw new Error(`Failed to fetch GitHub user: ${res.status}`);
|
|
54
|
+
const user = (await res.json());
|
|
55
|
+
return user.login;
|
|
56
|
+
}
|
|
57
|
+
function sleep(ms) {
|
|
58
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/lib/github.ts"],"names":[],"mappings":"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"}
|
package/dist/login.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../src/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAsB,QAAQ,IAAI,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CA0B3D;AAED,eAAO,MAAM,YAAY,SAIrB,CAAC"}
|
package/dist/login.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { readConfig, writeConfig } from './lib/config.js';
|
|
3
|
+
import { startDeviceFlow } from './lib/github.js';
|
|
4
|
+
const DEFAULT_CLIENT_ID = process.env.PAS_GITHUB_CLIENT_ID ?? 'Ov23liuUpYPXc1ikEFm2';
|
|
5
|
+
export async function runLogin() {
|
|
6
|
+
const flow = await startDeviceFlow(DEFAULT_CLIENT_ID);
|
|
7
|
+
process.stdout.write(`\nOpen ${flow.verificationUri} and enter code: ${flow.userCode}\n\n`);
|
|
8
|
+
process.stdout.write('Waiting for authorization...\n');
|
|
9
|
+
const { accessToken, login } = await flow.poll();
|
|
10
|
+
const config = await readConfig();
|
|
11
|
+
const exchangeUrl = `${config.authApiBase}/v1/auth/exchange`;
|
|
12
|
+
const exchangeRes = await fetch(exchangeUrl, {
|
|
13
|
+
method: 'POST',
|
|
14
|
+
headers: { 'Content-Type': 'application/json' },
|
|
15
|
+
body: JSON.stringify({ githubToken: accessToken }),
|
|
16
|
+
});
|
|
17
|
+
if (!exchangeRes.ok) {
|
|
18
|
+
throw new Error(`Auth exchange failed (${exchangeRes.status}): ${await exchangeRes.text()}`);
|
|
19
|
+
}
|
|
20
|
+
const { sessionToken } = (await exchangeRes.json());
|
|
21
|
+
await writeConfig({
|
|
22
|
+
...config,
|
|
23
|
+
github: { accessToken, login, obtainedAt: Date.now() },
|
|
24
|
+
session: { token: sessionToken, obtainedAt: Date.now() },
|
|
25
|
+
});
|
|
26
|
+
process.stdout.write(`\n✓ Signed in as @${login}\n`);
|
|
27
|
+
return { login };
|
|
28
|
+
}
|
|
29
|
+
export const loginCommand = new Command('login')
|
|
30
|
+
.description('Sign in with GitHub.')
|
|
31
|
+
.action(async () => {
|
|
32
|
+
await runLogin();
|
|
33
|
+
});
|
|
34
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../src/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,sBAAsB,CAAC;AAErF,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,iBAAiB,CAAC,CAAC;IACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,IAAI,CAAC,eAAe,oBAAoB,IAAI,CAAC,QAAQ,MAAM,CAAC,CAAC;IAC5F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;IAEvD,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;IACjD,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;IAElC,MAAM,WAAW,GAAG,GAAG,MAAM,CAAC,WAAW,mBAAmB,CAAC;IAC7D,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE;QAC3C,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;KACnD,CAAC,CAAC;IACH,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,yBAAyB,WAAW,CAAC,MAAM,MAAM,MAAM,WAAW,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAC/F,CAAC;IACD,MAAM,EAAE,YAAY,EAAE,GAAG,CAAC,MAAM,WAAW,CAAC,IAAI,EAAE,CAA6B,CAAC;IAEhF,MAAM,WAAW,CAAC;QAChB,GAAG,MAAM;QACT,MAAM,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE;QACtD,OAAO,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE;KACzD,CAAC,CAAC;IACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,KAAK,IAAI,CAAC,CAAC;IACrD,OAAO,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,sBAAsB,CAAC;KACnC,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,QAAQ,EAAE,CAAC;AACnB,CAAC,CAAC,CAAC"}
|
package/dist/publish.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"AAIA,UAAU,cAAc;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAoDD;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAgGpE"}
|
package/dist/publish.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { readFileSync, existsSync } from 'node:fs';
|
|
2
|
-
import { resolve } from 'node:path';
|
|
2
|
+
import { resolve, join } from 'node:path';
|
|
3
|
+
import { resolveToken } from './lib/config.js';
|
|
3
4
|
const PAS_API = 'https://api.proappstore.online';
|
|
4
5
|
function readJsonIfExists(path) {
|
|
5
6
|
if (!existsSync(path))
|
|
@@ -17,6 +18,31 @@ function toTitleCase(id) {
|
|
|
17
18
|
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
18
19
|
.join(' ');
|
|
19
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Map a failing step's detail to an actionable next-step hint. Returns
|
|
23
|
+
* null when the failure is generic ('Fix and retry' is enough). Hints are
|
|
24
|
+
* shown indented under the failing step line.
|
|
25
|
+
*/
|
|
26
|
+
function hintForStep(name, detail) {
|
|
27
|
+
const d = detail.toLowerCase();
|
|
28
|
+
if (d.includes('limit of projects') || d.includes('reached the limit')) {
|
|
29
|
+
return ('CF Pages cap: this account is at the 100-project ceiling.\n' +
|
|
30
|
+
'→ Free a slot: npx wrangler pages project list\n' +
|
|
31
|
+
' npx wrangler pages project delete <name>\n' +
|
|
32
|
+
'→ Long-term: PAS apps are scheduled to migrate to Path B\n' +
|
|
33
|
+
' (single host Worker + R2) which removes the cap.');
|
|
34
|
+
}
|
|
35
|
+
if (name.toLowerCase().includes('analytics') && d.includes('auth')) {
|
|
36
|
+
return ('CF Web Analytics token lacks the analytics scope.\n' +
|
|
37
|
+
'→ Non-blocking — your app still ships; the analytics dashboard\n' +
|
|
38
|
+
' will be empty until the platform token is widened.');
|
|
39
|
+
}
|
|
40
|
+
if (d.includes('repo') && d.includes('already exists')) {
|
|
41
|
+
return ('Repo already exists on GitHub. `pas publish` is idempotent —\n' +
|
|
42
|
+
'this step is harmless; the remaining steps still ran.');
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
20
46
|
/**
|
|
21
47
|
* Publish an existing repo to ProAppStore.
|
|
22
48
|
*
|
|
@@ -39,10 +65,9 @@ export async function publishApp(opts) {
|
|
|
39
65
|
process.stderr.write(`pas publish: package.json name "${appId}" is not a valid app id (lowercase, hyphens, max 58 chars).\n`);
|
|
40
66
|
process.exit(1);
|
|
41
67
|
}
|
|
42
|
-
const token = opts.token
|
|
68
|
+
const token = resolveToken(opts.token);
|
|
43
69
|
if (!token) {
|
|
44
|
-
process.stderr.write('pas publish: no auth token.
|
|
45
|
-
'Tokens come from `fas login` (shared identity with the free side).\n');
|
|
70
|
+
process.stderr.write('pas publish: no auth token. Run `pas login` first, or use --token.\n');
|
|
46
71
|
process.exit(1);
|
|
47
72
|
}
|
|
48
73
|
const name = opts.name || toTitleCase(appId);
|
|
@@ -85,6 +110,14 @@ export async function publishApp(opts) {
|
|
|
85
110
|
for (const step of data.steps) {
|
|
86
111
|
const icon = step.status === 'ok' ? '+' : step.status === 'skip' ? '-' : '!';
|
|
87
112
|
process.stdout.write(` [${icon}] ${step.name}: ${step.detail}\n`);
|
|
113
|
+
if (step.status === 'fail') {
|
|
114
|
+
const hint = hintForStep(step.name, step.detail);
|
|
115
|
+
if (hint) {
|
|
116
|
+
for (const line of hint.split('\n')) {
|
|
117
|
+
process.stdout.write(` ${line}\n`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
88
121
|
}
|
|
89
122
|
if (data.success) {
|
|
90
123
|
process.stdout.write(`\n Published. Push your code to deploy:\n`);
|
package/dist/publish.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@proappstore/cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "pas — CLI for publishing paid apps to proappstore.online",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
16
|
"dist",
|
|
17
|
+
"templates",
|
|
17
18
|
"README.md"
|
|
18
19
|
],
|
|
19
20
|
"engines": {
|
|
Binary file
|
|
Binary file
|