@wirechunk/cli 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/main.js +3807 -267
- package/package.json +6 -1
- package/src/commands/bootstrap.ts +1 -1
- package/src/commands/create-extension-version.ts +48 -102
- package/src/commands/ext-dev/{db-connect-info.ts → get-db-url.ts} +3 -3
- package/src/commands/ext-dev/init-db.ts +3 -2
- package/src/core-api/api.ts +4216 -0
- package/src/core-api/mutations/create-extension-version.generated.ts +96 -0
- package/src/core-api/mutations/create-extension-version.graphql +14 -0
- package/src/core-api/operations.ts +23 -0
- package/src/main.ts +9 -5
- package/src/users/permissions.ts +2 -2
- package/tsconfig.json +4 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wirechunk/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -19,17 +19,22 @@
|
|
|
19
19
|
"bin": {
|
|
20
20
|
"wirechunk": "build/main.js"
|
|
21
21
|
},
|
|
22
|
+
"imports": {
|
|
23
|
+
"#api": "./src/core-api/api.ts"
|
|
24
|
+
},
|
|
22
25
|
"dependencies": {
|
|
23
26
|
"argon2": "^0.41.1"
|
|
24
27
|
},
|
|
25
28
|
"devDependencies": {
|
|
26
29
|
"@commander-js/extra-typings": "^13.0.0",
|
|
30
|
+
"@graphql-typed-document-node/core": "^3.2.0",
|
|
27
31
|
"@types/archiver": "^6.0.3",
|
|
28
32
|
"@wirechunk/backend-lib": "0.0.0",
|
|
29
33
|
"@wirechunk/lib": "0.0.0",
|
|
30
34
|
"archiver": "^7.0.1",
|
|
31
35
|
"chalk": "^5.3.0",
|
|
32
36
|
"commander": "^13.0.0",
|
|
37
|
+
"graphql-request": "^7.1.2",
|
|
33
38
|
"slonik": "^46.3.0",
|
|
34
39
|
"slonik-interceptor-query-logging": "^46.3.0",
|
|
35
40
|
"zod": "^3.24.1"
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
2
|
import { cleanTinyId } from '@wirechunk/lib/clean-small-id.ts';
|
|
3
|
+
import { normalizeDomain } from '@wirechunk/lib/domains.ts';
|
|
3
4
|
import { normalizeEmailAddress } from '@wirechunk/lib/emails.ts';
|
|
4
5
|
import {
|
|
5
6
|
defaultFormattedDataTemplate,
|
|
6
7
|
defaultNotificationEmailBodyTemplate,
|
|
7
8
|
} from '@wirechunk/lib/mixer/form-formatting-templates.ts';
|
|
8
|
-
import { normalizeDomain } from '@wirechunk/server/site-domains/util.ts';
|
|
9
9
|
import type { DatabasePool } from 'slonik';
|
|
10
10
|
import { createPool, sql } from 'slonik';
|
|
11
11
|
import type { Env } from '../env.ts';
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { parseEnv } from 'node:util';
|
|
1
4
|
import { requireValidExtensionDir } from '@wirechunk/backend-lib/extensions/require-extension-dir.ts';
|
|
2
5
|
import { parseErrorMessage } from '@wirechunk/lib/errors.ts';
|
|
3
6
|
import archiver from 'archiver';
|
|
4
|
-
import {
|
|
7
|
+
import { GraphQLClient } from 'graphql-request';
|
|
8
|
+
import { createExtensionVersion as createExtensionVersionRequest } from '../core-api/operations.ts';
|
|
5
9
|
import type { Env } from '../env.ts';
|
|
6
10
|
import { requireApiToken } from '../env.ts';
|
|
7
11
|
import type { WithGlobalOptions } from '../global-options.js';
|
|
@@ -16,44 +20,21 @@ const bytesFormat = Intl.NumberFormat('en', {
|
|
|
16
20
|
maximumFractionDigits: 1,
|
|
17
21
|
});
|
|
18
22
|
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
message: z.string(),
|
|
30
|
-
}),
|
|
31
|
-
z.object({
|
|
32
|
-
__typename: z.literal('GenericInternalError'),
|
|
33
|
-
message: z.string(),
|
|
34
|
-
}),
|
|
35
|
-
z.object({
|
|
36
|
-
__typename: z.literal('GenericUserError'),
|
|
37
|
-
message: z.string(),
|
|
38
|
-
}),
|
|
39
|
-
]);
|
|
40
|
-
|
|
41
|
-
const graphQlErrorSchema = z.object({
|
|
42
|
-
message: z.string(),
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
const createExtensionVersionResultSchema = z.object({
|
|
46
|
-
errors: z.array(graphQlErrorSchema).optional().nullable(),
|
|
47
|
-
data: z
|
|
48
|
-
.object({
|
|
49
|
-
createExtensionVersion: createExtensionVersionResultDataSchema,
|
|
50
|
-
})
|
|
51
|
-
.nullable(),
|
|
52
|
-
});
|
|
23
|
+
const ignoreGlobs = [
|
|
24
|
+
'**/.git/**/*',
|
|
25
|
+
'.git/**/*',
|
|
26
|
+
'eslint.config.js',
|
|
27
|
+
'**/eslint.config.js',
|
|
28
|
+
'node_modules/**/*',
|
|
29
|
+
'**/node_modules/**/*',
|
|
30
|
+
'yalc.lock',
|
|
31
|
+
'**/yalc.lock',
|
|
32
|
+
];
|
|
53
33
|
|
|
54
34
|
type CreateExtensionVersionOptions = {
|
|
55
35
|
extensionId?: string;
|
|
56
36
|
versionName: string;
|
|
37
|
+
configFile?: string;
|
|
57
38
|
};
|
|
58
39
|
|
|
59
40
|
export const createExtensionVersion = async (
|
|
@@ -84,6 +65,20 @@ export const createExtensionVersion = async (
|
|
|
84
65
|
enableServer = false;
|
|
85
66
|
enableDb = false;
|
|
86
67
|
}
|
|
68
|
+
let config: Record<string, string> | null = null;
|
|
69
|
+
if (opts.configFile) {
|
|
70
|
+
const configFilePath = resolve(cwd, opts.configFile);
|
|
71
|
+
if (opts.verbose) {
|
|
72
|
+
console.log(`Loading config file ${configFilePath}`);
|
|
73
|
+
}
|
|
74
|
+
const configFile = await readFile(configFilePath, 'utf8');
|
|
75
|
+
try {
|
|
76
|
+
config = parseEnv(configFile) as Record<string, string>;
|
|
77
|
+
} catch (e) {
|
|
78
|
+
console.error(`Failed to parse config file at ${configFilePath}:`, parseErrorMessage(e));
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
87
82
|
|
|
88
83
|
const { versionName } = opts;
|
|
89
84
|
console.log(`Creating extension version ${versionName} (Extension ID ${extensionId})
|
|
@@ -98,69 +93,27 @@ export const createExtensionVersion = async (
|
|
|
98
93
|
if (opts.verbose) {
|
|
99
94
|
console.log(`POST ${url}`);
|
|
100
95
|
}
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
__typename
|
|
112
|
-
... on CreateExtensionVersionSuccessResult {
|
|
113
|
-
extensionVersion {
|
|
114
|
-
id
|
|
115
|
-
}
|
|
116
|
-
signedUrl
|
|
117
|
-
}
|
|
118
|
-
... on Error {
|
|
119
|
-
message
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
`,
|
|
124
|
-
variables: {
|
|
125
|
-
input: {
|
|
126
|
-
extensionId,
|
|
127
|
-
extensionName: extConfig.name,
|
|
128
|
-
versionName,
|
|
129
|
-
enableServer,
|
|
130
|
-
enableDb,
|
|
131
|
-
},
|
|
96
|
+
const result = await createExtensionVersionRequest({
|
|
97
|
+
client: new GraphQLClient(url),
|
|
98
|
+
variables: {
|
|
99
|
+
input: {
|
|
100
|
+
extensionId,
|
|
101
|
+
extensionName: extConfig.name,
|
|
102
|
+
versionName,
|
|
103
|
+
enableServer,
|
|
104
|
+
enableDb,
|
|
105
|
+
config: config ? JSON.stringify(config) : undefined,
|
|
132
106
|
},
|
|
133
|
-
}
|
|
107
|
+
},
|
|
108
|
+
sessionAuthToken: apiToken,
|
|
134
109
|
});
|
|
135
|
-
if (
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const data = await createResult.json();
|
|
139
|
-
console.error(`${message}:`, parseErrorMessage(data));
|
|
140
|
-
process.exit(1);
|
|
141
|
-
} catch {
|
|
142
|
-
console.error(message);
|
|
143
|
-
process.exit(1);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
const data = await createResult.json();
|
|
147
|
-
const parseResult = createExtensionVersionResultSchema.safeParse(data);
|
|
148
|
-
if (!parseResult.success) {
|
|
149
|
-
console.error('Failed to create an extension version:', parseResult.error.message);
|
|
150
|
-
process.exit(1);
|
|
151
|
-
}
|
|
152
|
-
const result = parseResult.data;
|
|
153
|
-
if (result.errors) {
|
|
154
|
-
console.error('Failed to create an extension version:', parseErrorMessage(result));
|
|
155
|
-
process.exit(1);
|
|
156
|
-
}
|
|
157
|
-
if (result.data?.createExtensionVersion.__typename === 'CreateExtensionVersionSuccessResult') {
|
|
158
|
-
extensionVersionId = result.data.createExtensionVersion.extensionVersion.id;
|
|
159
|
-
signedUrl = result.data.createExtensionVersion.signedUrl;
|
|
110
|
+
if (result.createExtensionVersion.__typename === 'CreateExtensionVersionSuccessResult') {
|
|
111
|
+
extensionVersionId = result.createExtensionVersion.extensionVersion.id;
|
|
112
|
+
signedUrl = result.createExtensionVersion.signedUrl;
|
|
160
113
|
} else {
|
|
161
114
|
console.error(
|
|
162
|
-
`Failed to create an extension version (${result.
|
|
163
|
-
|
|
115
|
+
`Failed to create an extension version (${result.createExtensionVersion.__typename}):`,
|
|
116
|
+
result.createExtensionVersion.message,
|
|
164
117
|
);
|
|
165
118
|
process.exit(1);
|
|
166
119
|
}
|
|
@@ -197,14 +150,7 @@ export const createExtensionVersion = async (
|
|
|
197
150
|
|
|
198
151
|
archive.glob('**/*', {
|
|
199
152
|
cwd,
|
|
200
|
-
ignore:
|
|
201
|
-
'**/.git/**/*',
|
|
202
|
-
'.git/**/*',
|
|
203
|
-
'eslint.config.js',
|
|
204
|
-
'**/eslint.config.js',
|
|
205
|
-
'node_modules/**/*',
|
|
206
|
-
'**/node_modules/**/*',
|
|
207
|
-
],
|
|
153
|
+
ignore: ignoreGlobs,
|
|
208
154
|
});
|
|
209
155
|
|
|
210
156
|
if (opts.verbose) {
|
|
@@ -5,13 +5,13 @@ import type { Env } from '../../env.ts';
|
|
|
5
5
|
import type { WithGlobalOptions } from '../../global-options.js';
|
|
6
6
|
import { getExtensionDbConnectInfo, replaceEnvVar } from '../../util.ts';
|
|
7
7
|
|
|
8
|
-
type
|
|
8
|
+
type GetDbUrlOptions = {
|
|
9
9
|
extensionId?: string;
|
|
10
10
|
dbName?: string;
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
export const
|
|
14
|
-
opts: WithGlobalOptions<
|
|
13
|
+
export const getDbUrl = async (
|
|
14
|
+
opts: WithGlobalOptions<GetDbUrlOptions>,
|
|
15
15
|
env: Env,
|
|
16
16
|
): Promise<void> => {
|
|
17
17
|
const connInfo = getExtensionDbConnectInfo(opts, env);
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
getExtensionDbConnectInfo,
|
|
11
11
|
requireExtensionIdOptionOrEnvVar,
|
|
12
12
|
} from '../../util.ts';
|
|
13
|
-
import {
|
|
13
|
+
import { getDbUrl } from './get-db-url.ts';
|
|
14
14
|
|
|
15
15
|
const initExtDb = async ({
|
|
16
16
|
// A connection to the extension database by a superuser role.
|
|
@@ -149,7 +149,8 @@ export const initDb = async (
|
|
|
149
149
|
const coreDbUrl = requireCoreDbUrl(env);
|
|
150
150
|
const extensionId = requireExtensionIdOptionOrEnvVar(opts, env);
|
|
151
151
|
|
|
152
|
-
|
|
152
|
+
// This writes the DATABASE_URL environment variable to a .env.local (or .env.<env-mode>.local) file.
|
|
153
|
+
await getDbUrl(opts, env);
|
|
153
154
|
|
|
154
155
|
const db = await createPool(coreDbUrl, dbPoolOptions(opts));
|
|
155
156
|
|