@appsemble/cli 0.21.2 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -11
- package/commands/app/create.d.ts +11 -24
- package/commands/app/create.js +98 -62
- package/commands/app/index.js +2 -0
- package/commands/app/publish.d.ts +27 -0
- package/commands/app/publish.js +75 -0
- package/commands/asset/index.js +2 -2
- package/commands/asset/{create.d.ts → publish.d.ts} +4 -4
- package/commands/asset/{create.js → publish.js} +8 -8
- package/commands/block/create.d.ts +12 -0
- package/commands/block/create.js +66 -0
- package/commands/block/delete.d.ts +11 -0
- package/commands/block/delete.js +22 -0
- package/commands/block/index.js +4 -0
- package/commands/migrate.js +2 -2
- package/commands/resource/index.js +2 -2
- package/commands/resource/{create.d.ts → publish.d.ts} +4 -4
- package/commands/resource/{create.js → publish.js} +8 -8
- package/commands/serve.js +20 -14
- package/index.js +2 -3
- package/lib/app.d.ts +8 -9
- package/lib/app.js +8 -8
- package/lib/asset.d.ts +4 -4
- package/lib/asset.js +2 -2
- package/lib/block.d.ts +8 -0
- package/lib/block.js +6 -6
- package/lib/createServers.js +13 -9
- package/lib/getBlockConfigFromTypeScript.test.js +3 -1
- package/lib/initAxios.js +2 -3
- package/lib/resource.d.ts +5 -5
- package/lib/resource.js +3 -3
- package/package.json +14 -7
- package/server/db/methods.js +5 -1
- package/server/options/getAppBlockStyles.js +17 -17
- package/server/options/parseQuery.js +13 -9
- package/templates/apps/empty/.appsemblerc.yaml +15 -0
- package/templates/apps/empty/app-definition.yaml +26 -0
- package/templates/apps/empty/assets/.gitkeep +0 -0
- package/templates/apps/empty/i18n/en.json +0 -0
- package/templates/apps/empty/resources/.gitkeep +0 -0
- package/templates/apps/empty/themes/@appsemble/.gitkeep +0 -0
- package/templates/apps/empty/themes/core/index.css +3 -0
- package/templates/apps/empty/themes/shared/index.css +3 -0
- package/templates/blocks/mini-jsx/.appsemblerc.yaml +1 -0
- package/templates/blocks/mini-jsx/README.md +11 -0
- package/templates/blocks/mini-jsx/block.ts +48 -0
- package/templates/blocks/mini-jsx/i18n/en.json +3 -0
- package/templates/blocks/mini-jsx/package.json +8 -0
- package/templates/blocks/mini-jsx/src/index.module.css +19 -0
- package/templates/blocks/mini-jsx/src/index.tsx +61 -0
- package/templates/blocks/mini-jsx/tsconfig.json +9 -0
- package/templates/blocks/preact/.appsemblerc.yaml +1 -0
- package/templates/blocks/preact/README.md +11 -0
- package/templates/blocks/preact/block.ts +37 -0
- package/templates/blocks/preact/i18n/en.json +5 -0
- package/templates/blocks/preact/package.json +9 -0
- package/templates/blocks/preact/src/index.tsx +99 -0
- package/templates/blocks/preact/tsconfig.json +9 -0
- package/templates/blocks/vanilla/.appsemblerc.yaml +1 -0
- package/templates/blocks/vanilla/README.md +10 -0
- package/templates/blocks/vanilla/block.ts +20 -0
- package/templates/blocks/vanilla/i18n/en.json +3 -0
- package/templates/blocks/vanilla/package.json +7 -0
- package/templates/blocks/vanilla/src/index.ts +25 -0
- package/templates/blocks/vanilla/tsconfig.json +7 -0
- package/types.d.ts +0 -46
- package/vitest.config.d.ts +0 -2
package/commands/block/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import * as build from './build.js';
|
|
2
|
+
import * as create from './create.js';
|
|
3
|
+
import * as remove from './delete.js';
|
|
2
4
|
import * as extractMessages from './extract-messages.js';
|
|
3
5
|
import * as publish from './publish.js';
|
|
4
6
|
export { noop as handler } from '@appsemble/utils';
|
|
@@ -7,8 +9,10 @@ export const description = 'Commands related to blocks.';
|
|
|
7
9
|
export function builder(yargs) {
|
|
8
10
|
return yargs
|
|
9
11
|
.command(build)
|
|
12
|
+
.command(create)
|
|
10
13
|
.command(extractMessages)
|
|
11
14
|
.command(publish)
|
|
15
|
+
.command(remove)
|
|
12
16
|
.demandCommand(1);
|
|
13
17
|
}
|
|
14
18
|
//# sourceMappingURL=index.js.map
|
package/commands/migrate.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import { version } from '@appsemble/node-utils';
|
|
1
2
|
import { serverImport } from '../lib/serverImport.js';
|
|
2
|
-
import pkg from '../package.json' assert { type: 'json' };
|
|
3
3
|
export const command = 'migrate [migrate-to]';
|
|
4
4
|
export const description = 'Migrate the Appsemble database';
|
|
5
5
|
export function builder(yargs) {
|
|
6
6
|
return yargs
|
|
7
7
|
.positional('migrate-to', {
|
|
8
8
|
desc: 'The database version to migrate to.',
|
|
9
|
-
default:
|
|
9
|
+
default: version,
|
|
10
10
|
})
|
|
11
11
|
.option('database-host', {
|
|
12
12
|
desc: 'The host of the database to connect to. This defaults to the connected database container.',
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as publish from './publish.js';
|
|
2
2
|
import * as update from './update.js';
|
|
3
3
|
export { noop as handler } from '@appsemble/utils';
|
|
4
4
|
export const command = 'resource';
|
|
5
5
|
export const description = 'Commands related to resources.';
|
|
6
6
|
export function builder(yargs) {
|
|
7
7
|
return yargs
|
|
8
|
-
.command(
|
|
8
|
+
.command(publish)
|
|
9
9
|
.command(update)
|
|
10
10
|
.demandCommand(1);
|
|
11
11
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { type Argv } from 'yargs';
|
|
2
2
|
import { type BaseArguments } from '../../types.js';
|
|
3
|
-
interface
|
|
3
|
+
interface PublishResourceArguments extends BaseArguments {
|
|
4
4
|
resourceName: string;
|
|
5
5
|
paths: string[];
|
|
6
6
|
appId: number;
|
|
7
7
|
context: string;
|
|
8
8
|
app: string;
|
|
9
9
|
}
|
|
10
|
-
export declare const command = "
|
|
11
|
-
export declare const description = "
|
|
10
|
+
export declare const command = "publish <resource-name> <paths...>";
|
|
11
|
+
export declare const description = "Publish resources based on a specified JSON file or directory.";
|
|
12
12
|
export declare function builder(yargs: Argv): Argv<any>;
|
|
13
|
-
export declare function handler({ app, appId, clientCredentials, context, paths, remote, resourceName, }:
|
|
13
|
+
export declare function handler({ app, appId, clientCredentials, context, paths, remote, resourceName, }: PublishResourceArguments): Promise<void>;
|
|
14
14
|
export {};
|
|
@@ -3,22 +3,22 @@ import fg from 'fast-glob';
|
|
|
3
3
|
import normalizePath from 'normalize-path';
|
|
4
4
|
import { resolveAppIdAndRemote } from '../../lib/app.js';
|
|
5
5
|
import { authenticate } from '../../lib/authentication.js';
|
|
6
|
-
import {
|
|
7
|
-
export const command = '
|
|
8
|
-
export const description = '
|
|
6
|
+
import { publishResource } from '../../lib/resource.js';
|
|
7
|
+
export const command = 'publish <resource-name> <paths...>';
|
|
8
|
+
export const description = 'Publish resources based on a specified JSON file or directory.';
|
|
9
9
|
export function builder(yargs) {
|
|
10
10
|
return yargs
|
|
11
11
|
.positional('resource-name', {
|
|
12
|
-
describe: 'The name of the resource that should be
|
|
12
|
+
describe: 'The name of the resource that should be published.',
|
|
13
13
|
demandOption: true,
|
|
14
14
|
})
|
|
15
15
|
.positional('paths', {
|
|
16
|
-
describe: 'The path to the resources to
|
|
16
|
+
describe: 'The path to the resources to publish',
|
|
17
17
|
normalize: true,
|
|
18
18
|
demandOption: true,
|
|
19
19
|
})
|
|
20
20
|
.option('app-id', {
|
|
21
|
-
describe: 'The ID of the app to
|
|
21
|
+
describe: 'The ID of the app to publish the resources for.',
|
|
22
22
|
type: 'number',
|
|
23
23
|
})
|
|
24
24
|
.option('app', {
|
|
@@ -41,7 +41,7 @@ export async function handler({ app, appId, clientCredentials, context, paths, r
|
|
|
41
41
|
logger.info(`Creating resources based on ${files.length} files`);
|
|
42
42
|
for (const path of files) {
|
|
43
43
|
logger.info('');
|
|
44
|
-
await
|
|
44
|
+
await publishResource({
|
|
45
45
|
resourceName,
|
|
46
46
|
appId: resolvedAppId,
|
|
47
47
|
path,
|
|
@@ -49,4 +49,4 @@ export async function handler({ app, appId, clientCredentials, context, paths, r
|
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
//# sourceMappingURL=
|
|
52
|
+
//# sourceMappingURL=publish.js.map
|
package/commands/serve.js
CHANGED
|
@@ -129,21 +129,26 @@ export async function handler(argv) {
|
|
|
129
129
|
const cacheExists = existsSync(cachedBlockManifest);
|
|
130
130
|
if (!cacheExists || (cacheExists && argv['overwrite-block-cache'])) {
|
|
131
131
|
const blockUrl = `/api/blocks/@${organization}/${blockName}/versions/${identifiableBlock.version}`;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
132
|
+
try {
|
|
133
|
+
const { data: blockManifest } = await axios.get(String(new URL(blockUrl, argv.remote)));
|
|
134
|
+
await writeData(cachedBlockManifest, blockManifest);
|
|
135
|
+
const assetsDir = join(blockCacheDir, 'assets');
|
|
136
|
+
if (!existsSync(assetsDir)) {
|
|
137
|
+
await mkdir(assetsDir);
|
|
138
|
+
}
|
|
139
|
+
const blockFilesPromises = blockManifest.files.map(async (filename) => {
|
|
140
|
+
const writer = createWriteStream(join(assetsDir, filename));
|
|
141
|
+
const { data: content } = await axios.get(String(new URL(`${blockUrl}/asset?filename=${filename}`, argv.remote)), {
|
|
142
|
+
responseType: 'stream',
|
|
143
|
+
});
|
|
144
|
+
content.pipe(writer);
|
|
142
145
|
});
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
146
|
+
await Promise.all(blockFilesPromises);
|
|
147
|
+
return blockManifest;
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
throw new AppsembleError(`The server was unable to fetch the "${blockName}" block\nThis could be due to a misconfigured remote\nMake sure the passed remote supports fetching blocks such as https://appsemble.app`);
|
|
151
|
+
}
|
|
147
152
|
}
|
|
148
153
|
const [blockManifest] = await readData(cachedBlockManifest);
|
|
149
154
|
return blockManifest;
|
|
@@ -230,6 +235,7 @@ export async function handler(argv) {
|
|
|
230
235
|
const api = http.createServer(appsembleApiServer.callback());
|
|
231
236
|
const staticServer = await createStaticServer({
|
|
232
237
|
context: {
|
|
238
|
+
appPath,
|
|
233
239
|
apiUrl: `http://localhost:${argv['api-port']}`,
|
|
234
240
|
appHost: `http://localhost:${argv.port}`,
|
|
235
241
|
appsembleApp: stubbedApp,
|
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import process from 'node:process';
|
|
3
|
-
import { configureLogger, handleError } from '@appsemble/node-utils';
|
|
3
|
+
import { configureLogger, handleError, version } from '@appsemble/node-utils';
|
|
4
4
|
import { cosmiconfig } from 'cosmiconfig';
|
|
5
5
|
import yargs from 'yargs';
|
|
6
6
|
import * as app from './commands/app/index.js';
|
|
@@ -20,12 +20,11 @@ import * as team from './commands/team/index.js';
|
|
|
20
20
|
import { CREDENTIALS_ENV_VAR } from './lib/authentication.js';
|
|
21
21
|
import { coerceRemote } from './lib/coercers.js';
|
|
22
22
|
import { initAxios } from './lib/initAxios.js';
|
|
23
|
-
import pkg from './package.json' assert { type: 'json' };
|
|
24
23
|
process.title = 'appsemble';
|
|
25
24
|
const explorer = cosmiconfig('appsembleServer');
|
|
26
25
|
const found = await explorer.search(process.cwd());
|
|
27
26
|
let parser = yargs(process.argv.slice(2))
|
|
28
|
-
.version(
|
|
27
|
+
.version(version)
|
|
29
28
|
.option('verbose', {
|
|
30
29
|
alias: 'v',
|
|
31
30
|
describe: 'Increase verbosity',
|
package/lib/app.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
2
|
/// <reference types="node" resolution-mode="require"/>
|
|
3
3
|
import { type ReadStream } from 'node:fs';
|
|
4
|
-
import { type App, type AppVisibility } from '@appsemble/types';
|
|
4
|
+
import { type App, type AppsembleContext, type AppsembleRC, type AppVisibility } from '@appsemble/types';
|
|
5
5
|
import FormData from 'form-data';
|
|
6
|
-
|
|
7
|
-
interface CreateAppParams {
|
|
6
|
+
interface PublishAppParams {
|
|
8
7
|
/**
|
|
9
8
|
* The OAuth2 client credentials to use.
|
|
10
9
|
*/
|
|
@@ -26,7 +25,7 @@ interface CreateAppParams {
|
|
|
26
25
|
*/
|
|
27
26
|
visibility: AppVisibility;
|
|
28
27
|
/**
|
|
29
|
-
* The remote server to
|
|
28
|
+
* The remote server to publish the app on.
|
|
30
29
|
*/
|
|
31
30
|
remote: string;
|
|
32
31
|
/**
|
|
@@ -50,12 +49,12 @@ interface CreateAppParams {
|
|
|
50
49
|
*/
|
|
51
50
|
dryRun: boolean;
|
|
52
51
|
/**
|
|
53
|
-
* Whether resources from the `resources` directory should be
|
|
52
|
+
* Whether resources from the `resources` directory should be published after publishing the app.
|
|
54
53
|
*/
|
|
55
54
|
resources: boolean;
|
|
56
55
|
/**
|
|
57
56
|
* If the app context is specified,
|
|
58
|
-
* modify it for the current context to include the id of the
|
|
57
|
+
* modify it for the current context to include the id of the published app.
|
|
59
58
|
*/
|
|
60
59
|
modifyContext: boolean;
|
|
61
60
|
/**
|
|
@@ -162,11 +161,11 @@ export declare function writeAppMessages(path: string, languages: string[], veri
|
|
|
162
161
|
*/
|
|
163
162
|
export declare function updateApp({ clientCredentials, context, force, path, ...options }: UpdateAppParams): Promise<void>;
|
|
164
163
|
/**
|
|
165
|
-
*
|
|
164
|
+
* Publish a new app.
|
|
166
165
|
*
|
|
167
|
-
* @param options The options to use for
|
|
166
|
+
* @param options The options to use for publishing an app.
|
|
168
167
|
*/
|
|
169
|
-
export declare function
|
|
168
|
+
export declare function publishApp({ clientCredentials, context, dryRun, modifyContext, path, resources, ...options }: PublishAppParams): Promise<void>;
|
|
170
169
|
/**
|
|
171
170
|
* Resolve the app’s ID and remote based on the app context.
|
|
172
171
|
*
|
package/lib/app.js
CHANGED
|
@@ -11,7 +11,7 @@ import { traverseBlockThemes } from './block.js';
|
|
|
11
11
|
import { coerceRemote } from './coercers.js';
|
|
12
12
|
import { printAxiosError } from './output.js';
|
|
13
13
|
import { processCss } from './processCss.js';
|
|
14
|
-
import {
|
|
14
|
+
import { publishResource } from './resource.js';
|
|
15
15
|
/**
|
|
16
16
|
* Traverses an app directory and appends the files it finds to the given FormData object.
|
|
17
17
|
*
|
|
@@ -88,7 +88,7 @@ export async function traverseAppDirectory(path, context, formData) {
|
|
|
88
88
|
}
|
|
89
89
|
const css = await processCss(join(themeDir, 'index.css'));
|
|
90
90
|
formData.append(`${name}Style`, css);
|
|
91
|
-
gatheredData[`${name}Style`] =
|
|
91
|
+
gatheredData[`${name}Style`] = css;
|
|
92
92
|
});
|
|
93
93
|
default:
|
|
94
94
|
logger.warn(`Found unused file ${filepath}`);
|
|
@@ -358,11 +358,11 @@ export async function updateApp({ clientCredentials, context, force, path, ...op
|
|
|
358
358
|
logger.info(`App store page: ${new URL(`/apps/${data.id}`, remote)}`);
|
|
359
359
|
}
|
|
360
360
|
/**
|
|
361
|
-
*
|
|
361
|
+
* Publish a new app.
|
|
362
362
|
*
|
|
363
|
-
* @param options The options to use for
|
|
363
|
+
* @param options The options to use for publishing an app.
|
|
364
364
|
*/
|
|
365
|
-
export async function
|
|
365
|
+
export async function publishApp({ clientCredentials, context, dryRun, modifyContext, path, resources, ...options }) {
|
|
366
366
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
|
|
367
367
|
const file = await stat(path);
|
|
368
368
|
const formData = new FormData();
|
|
@@ -456,7 +456,7 @@ export async function createApp({ clientCredentials, context, dryRun, modifyCont
|
|
|
456
456
|
for (const resource of resourceFiles) {
|
|
457
457
|
if (resource.isFile()) {
|
|
458
458
|
const { name } = parse(resource.name);
|
|
459
|
-
await
|
|
459
|
+
await publishResource({
|
|
460
460
|
appId: data.id,
|
|
461
461
|
path: join(resourcePath, resource.name),
|
|
462
462
|
remote,
|
|
@@ -468,7 +468,7 @@ export async function createApp({ clientCredentials, context, dryRun, modifyCont
|
|
|
468
468
|
withFileTypes: true,
|
|
469
469
|
});
|
|
470
470
|
for (const subResource of subDirectoryResources.filter((s) => s.isFile())) {
|
|
471
|
-
await
|
|
471
|
+
await publishResource({
|
|
472
472
|
appId: data.id,
|
|
473
473
|
path: join(resourcePath, resource.name, subResource.name),
|
|
474
474
|
remote,
|
|
@@ -490,7 +490,7 @@ export async function createApp({ clientCredentials, context, dryRun, modifyCont
|
|
|
490
490
|
logger.info(`Updated .appsemblerc: Set context.${context}.id to ${data.id}`);
|
|
491
491
|
}
|
|
492
492
|
const { host, protocol } = new URL(remote);
|
|
493
|
-
logger.info(`Successfully
|
|
493
|
+
logger.info(`Successfully published app ${data.definition.name}! 🙌`);
|
|
494
494
|
logger.info(`App URL: ${protocol}//${data.path}.${data.OrganizationId}.${host}`);
|
|
495
495
|
logger.info(`App store page: ${new URL(`/apps/${data.id}`, remote)}`);
|
|
496
496
|
}
|
package/lib/asset.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
interface
|
|
1
|
+
interface PublishAssetParams {
|
|
2
2
|
/**
|
|
3
3
|
* The name of the asset being uploaded.
|
|
4
4
|
* This must be a unique name for the app. If left empty, the ID is used instead.
|
|
@@ -9,13 +9,13 @@ interface CreateAssetParams {
|
|
|
9
9
|
*/
|
|
10
10
|
path: string;
|
|
11
11
|
/**
|
|
12
|
-
* The ID of the app to
|
|
12
|
+
* The ID of the app to publish a resource entry for.
|
|
13
13
|
*/
|
|
14
14
|
appId: number;
|
|
15
15
|
/**
|
|
16
|
-
* The remote server to
|
|
16
|
+
* The remote server to publish the asset on.
|
|
17
17
|
*/
|
|
18
18
|
remote: string;
|
|
19
19
|
}
|
|
20
|
-
export declare function
|
|
20
|
+
export declare function publishAsset({ appId, name, path, remote, }: PublishAssetParams): Promise<void>;
|
|
21
21
|
export {};
|
package/lib/asset.js
CHANGED
|
@@ -3,7 +3,7 @@ import { logger } from '@appsemble/node-utils';
|
|
|
3
3
|
import { normalize } from '@appsemble/utils';
|
|
4
4
|
import axios from 'axios';
|
|
5
5
|
import FormData from 'form-data';
|
|
6
|
-
export async function
|
|
6
|
+
export async function publishAsset({ appId, name, path, remote, }) {
|
|
7
7
|
const formData = new FormData();
|
|
8
8
|
const file = createReadStream(path);
|
|
9
9
|
formData.append('file', file);
|
|
@@ -11,6 +11,6 @@ export async function createAsset({ appId, name, path, remote }) {
|
|
|
11
11
|
formData.append('name', normalize(name));
|
|
12
12
|
}
|
|
13
13
|
const { data: { id }, } = await axios.post(`/api/apps/${appId}/assets`, formData, { baseURL: remote });
|
|
14
|
-
logger.info(`
|
|
14
|
+
logger.info(`Published asset ${id}${name ? ` with name ${normalize(name)}` : ''}`);
|
|
15
15
|
}
|
|
16
16
|
//# sourceMappingURL=asset.js.map
|
package/lib/block.d.ts
CHANGED
|
@@ -7,7 +7,14 @@ import { type Stats } from 'webpack';
|
|
|
7
7
|
* @param config The config of the block to build.
|
|
8
8
|
* @returns The Webpack stats object.
|
|
9
9
|
*/
|
|
10
|
+
interface DeleteBlockVersionParams {
|
|
11
|
+
organization: string;
|
|
12
|
+
blockName: string;
|
|
13
|
+
blockVersion: string;
|
|
14
|
+
remote: string;
|
|
15
|
+
}
|
|
10
16
|
export declare function buildBlock(config: BlockConfig): Promise<Stats>;
|
|
17
|
+
export declare function deleteBlock({ blockName, blockVersion, organization, remote, }: DeleteBlockVersionParams): Promise<void>;
|
|
11
18
|
/**
|
|
12
19
|
* Get the block configuration from a block directory.
|
|
13
20
|
*
|
|
@@ -59,3 +66,4 @@ export declare function uploadAppBlockTheme(filePath: string, organization: stri
|
|
|
59
66
|
*/
|
|
60
67
|
export declare function traverseBlockThemes(path: string, appId: number, remote: string, force: boolean): Promise<void>;
|
|
61
68
|
export declare function processBlockMessages(config: BlockConfig, languages: string[]): Promise<void>;
|
|
69
|
+
export {};
|
package/lib/block.js
CHANGED
|
@@ -12,12 +12,6 @@ import webpack from 'webpack';
|
|
|
12
12
|
import { getBlockConfigFromTypeScript } from './getBlockConfigFromTypeScript.js';
|
|
13
13
|
import { loadWebpackConfig } from './loadWebpackConfig.js';
|
|
14
14
|
import { processCss } from './processCss.js';
|
|
15
|
-
/**
|
|
16
|
-
* Builds a block using Webpack.
|
|
17
|
-
*
|
|
18
|
-
* @param config The config of the block to build.
|
|
19
|
-
* @returns The Webpack stats object.
|
|
20
|
-
*/
|
|
21
15
|
export async function buildBlock(config) {
|
|
22
16
|
const conf = await loadWebpackConfig(config, 'production', join(config.dir, config.output));
|
|
23
17
|
if (existsSync(conf.output.path)) {
|
|
@@ -41,6 +35,12 @@ export async function buildBlock(config) {
|
|
|
41
35
|
});
|
|
42
36
|
});
|
|
43
37
|
}
|
|
38
|
+
export async function deleteBlock({ blockName, blockVersion, organization, remote, }) {
|
|
39
|
+
await axios.delete(`/api/blocks/@${organization}/${blockName}/versions/${blockVersion}`, {
|
|
40
|
+
baseURL: remote,
|
|
41
|
+
});
|
|
42
|
+
logger.info(`Successfully deleted ${blockName} block version.`);
|
|
43
|
+
}
|
|
44
44
|
/**
|
|
45
45
|
* Get the block configuration from a block directory.
|
|
46
46
|
*
|
package/lib/createServers.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { bodyParser,
|
|
1
|
+
import { bodyParser, conditional, errorMiddleware, frontend, loggerMiddleware, parameters, serializer, version, } from '@appsemble/node-utils';
|
|
2
2
|
import { api } from '@appsemble/utils';
|
|
3
|
-
import { notFound } from '@hapi/boom';
|
|
4
3
|
import cors from '@koa/cors';
|
|
5
4
|
import Koa from 'koa';
|
|
6
5
|
import compose from 'koa-compose';
|
|
@@ -9,14 +8,13 @@ import range from 'koa-range';
|
|
|
9
8
|
import { koas } from 'koas-core';
|
|
10
9
|
import { operations } from 'koas-operations';
|
|
11
10
|
import { statusCode } from 'koas-status-code';
|
|
12
|
-
import pkg from '../package.json' assert { type: 'json' };
|
|
13
11
|
import { argv } from '../server/argv.js';
|
|
14
12
|
import * as controllers from '../server/controllers/index.js';
|
|
15
13
|
import { appRouter } from '../server/routes/appRouter/index.js';
|
|
16
14
|
export async function createStaticServer({ context, webpackConfigs, }) {
|
|
17
15
|
const app = new Koa();
|
|
18
16
|
app.use(loggerMiddleware());
|
|
19
|
-
app.use(
|
|
17
|
+
app.use(errorMiddleware());
|
|
20
18
|
app.use(range);
|
|
21
19
|
Object.assign(app.context, context);
|
|
22
20
|
if (process.env.NODE_ENV === 'production') {
|
|
@@ -31,7 +29,7 @@ export async function createStaticServer({ context, webpackConfigs, }) {
|
|
|
31
29
|
export function createApiServer({ context }) {
|
|
32
30
|
const app = new Koa();
|
|
33
31
|
app.use(loggerMiddleware());
|
|
34
|
-
app.use(
|
|
32
|
+
app.use(errorMiddleware());
|
|
35
33
|
app.use(range);
|
|
36
34
|
Object.assign(app.context, context);
|
|
37
35
|
if (process.env.NODE_ENV === 'production') {
|
|
@@ -39,16 +37,22 @@ export function createApiServer({ context }) {
|
|
|
39
37
|
}
|
|
40
38
|
app.use(compose([
|
|
41
39
|
conditional((ctx) => ctx.path.startsWith('/api') || ctx.path === '/oauth2/token', cors()),
|
|
42
|
-
koas(api(
|
|
40
|
+
koas(api(version, argv), [
|
|
43
41
|
parameters(),
|
|
44
42
|
bodyParser(),
|
|
45
43
|
serializer(),
|
|
46
44
|
statusCode(),
|
|
47
45
|
operations({ controllers, throwOnNotImplemented: false }),
|
|
48
46
|
]),
|
|
49
|
-
(
|
|
50
|
-
if (path.startsWith('/api/')) {
|
|
51
|
-
|
|
47
|
+
(ctx, next) => {
|
|
48
|
+
if (ctx.path.startsWith('/api/')) {
|
|
49
|
+
ctx.response.status = 404;
|
|
50
|
+
ctx.response.body = {
|
|
51
|
+
statusCode: 404,
|
|
52
|
+
error: 'Not Found',
|
|
53
|
+
message: 'URL not found',
|
|
54
|
+
};
|
|
55
|
+
ctx.throw();
|
|
52
56
|
}
|
|
53
57
|
return next();
|
|
54
58
|
},
|
|
@@ -49,7 +49,9 @@ describe('getBlockConfigFromTypeScript', () => {
|
|
|
49
49
|
},
|
|
50
50
|
});
|
|
51
51
|
});
|
|
52
|
-
|
|
52
|
+
// Spying on TypeScript functions no longer works.
|
|
53
|
+
// eslint-disable-next-line vitest/no-disabled-tests
|
|
54
|
+
it.skip('should not use TypeScript if all metadata is present in the original config', () => {
|
|
53
55
|
vi.spyOn(ts, 'createProgram');
|
|
54
56
|
const input = {
|
|
55
57
|
actions: {},
|
package/lib/initAxios.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { configureAxios, logger } from '@appsemble/node-utils';
|
|
1
|
+
import { configureAxios, logger, version } from '@appsemble/node-utils';
|
|
2
2
|
import axios from 'axios';
|
|
3
|
-
import pkg from '../package.json' assert { type: 'json' };
|
|
4
3
|
/**
|
|
5
4
|
* Configure the default axios URL.
|
|
6
5
|
*
|
|
@@ -9,6 +8,6 @@ import pkg from '../package.json' assert { type: 'json' };
|
|
|
9
8
|
export function initAxios({ remote }) {
|
|
10
9
|
axios.defaults.baseURL = remote;
|
|
11
10
|
logger.verbose(`Request remote set to ${remote}`);
|
|
12
|
-
configureAxios('AppsembleCLI',
|
|
11
|
+
configureAxios('AppsembleCLI', version);
|
|
13
12
|
}
|
|
14
13
|
//# sourceMappingURL=initAxios.js.map
|
package/lib/resource.d.ts
CHANGED
|
@@ -12,11 +12,11 @@ interface UpdateResourceParams {
|
|
|
12
12
|
*/
|
|
13
13
|
appId: number;
|
|
14
14
|
/**
|
|
15
|
-
* The remote server to create the
|
|
15
|
+
* The remote server to create the resource on.
|
|
16
16
|
*/
|
|
17
17
|
remote: string;
|
|
18
18
|
}
|
|
19
|
-
interface
|
|
19
|
+
interface PublishResourceParams {
|
|
20
20
|
/**
|
|
21
21
|
* The name of the resource that a new entry is being created of.
|
|
22
22
|
*/
|
|
@@ -26,14 +26,14 @@ interface CreateResourceParams {
|
|
|
26
26
|
*/
|
|
27
27
|
path: string;
|
|
28
28
|
/**
|
|
29
|
-
* The ID of the app to
|
|
29
|
+
* The ID of the app to publish a resource entry for.
|
|
30
30
|
*/
|
|
31
31
|
appId: number;
|
|
32
32
|
/**
|
|
33
|
-
* The remote server to
|
|
33
|
+
* The remote server to publish the resource on.
|
|
34
34
|
*/
|
|
35
35
|
remote: string;
|
|
36
36
|
}
|
|
37
|
-
export declare function
|
|
37
|
+
export declare function publishResource({ appId, path, remote, resourceName, }: PublishResourceParams): Promise<void>;
|
|
38
38
|
export declare function updateResource({ appId, path, remote, resourceName, }: UpdateResourceParams): Promise<void>;
|
|
39
39
|
export {};
|
package/lib/resource.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { AppsembleError, logger, readData } from '@appsemble/node-utils';
|
|
3
3
|
import axios from 'axios';
|
|
4
|
-
export async function
|
|
4
|
+
export async function publishResource({ appId, path, remote, resourceName, }) {
|
|
5
5
|
const csv = path.endsWith('.csv');
|
|
6
6
|
let resources;
|
|
7
7
|
if (csv) {
|
|
@@ -14,14 +14,14 @@ export async function createResource({ appId, path, remote, resourceName, }) {
|
|
|
14
14
|
}
|
|
15
15
|
resources = [].concat(file);
|
|
16
16
|
}
|
|
17
|
-
logger.info(`
|
|
17
|
+
logger.info(`Publishing resource(s) from ${path}`);
|
|
18
18
|
const { data } = await axios.post(`/api/apps/${appId}/resources/${resourceName}`, resources, {
|
|
19
19
|
baseURL: remote,
|
|
20
20
|
headers: { 'content-type': csv ? 'text/csv' : 'application/json' },
|
|
21
21
|
});
|
|
22
22
|
const ids = [].concat(data).map((d) => d.id);
|
|
23
23
|
const url = new URL(`/apps/${appId}/resources/${resourceName}/`, remote);
|
|
24
|
-
logger.info(`Successfully
|
|
24
|
+
logger.info(`Successfully published ${ids.length} resource${resources.length === 1 ? '' : 's'} at: \n${ids
|
|
25
25
|
.map((id) => `${url}${id}`)
|
|
26
26
|
.join('\n')}`);
|
|
27
27
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appsemble/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "The CLI for developing with Appsemble apps and blocks",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"app",
|
|
@@ -21,24 +21,31 @@
|
|
|
21
21
|
"license": "LGPL-3.0-only",
|
|
22
22
|
"author": "Appsemble <info@appsemble.com> (https://appsemble.com)",
|
|
23
23
|
"type": "module",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": [
|
|
26
|
+
"./index.js",
|
|
27
|
+
"./index.ts"
|
|
28
|
+
],
|
|
29
|
+
"./README.md": "./README.md"
|
|
30
|
+
},
|
|
24
31
|
"bin": {
|
|
25
32
|
"appsemble": "index.js"
|
|
26
33
|
},
|
|
27
34
|
"files": [
|
|
28
35
|
"**/*.d.ts",
|
|
29
36
|
"**/*.js",
|
|
30
|
-
"!*.config.js"
|
|
37
|
+
"!*.config.js",
|
|
38
|
+
"templates"
|
|
31
39
|
],
|
|
32
40
|
"scripts": {
|
|
33
41
|
"prepack": "tsc --noEmit false",
|
|
34
42
|
"test": "vitest"
|
|
35
43
|
},
|
|
36
44
|
"dependencies": {
|
|
37
|
-
"@appsemble/node-utils": "0.
|
|
38
|
-
"@appsemble/types": "0.
|
|
39
|
-
"@appsemble/utils": "0.
|
|
45
|
+
"@appsemble/node-utils": "0.22.0",
|
|
46
|
+
"@appsemble/types": "0.22.0",
|
|
47
|
+
"@appsemble/utils": "0.22.0",
|
|
40
48
|
"@fortawesome/fontawesome-common-types": "^6.0.0",
|
|
41
|
-
"@hapi/boom": "^10.0.0",
|
|
42
49
|
"@koa/cors": "^4.0.0",
|
|
43
50
|
"@odata/parser": "^0.2.0",
|
|
44
51
|
"axios": "^1.0.0",
|
|
@@ -78,7 +85,7 @@
|
|
|
78
85
|
"yargs": "^17.0.0"
|
|
79
86
|
},
|
|
80
87
|
"devDependencies": {
|
|
81
|
-
"@appsemble/types": "0.
|
|
88
|
+
"@appsemble/types": "0.22.0",
|
|
82
89
|
"@types/concat-stream": "^2.0.0",
|
|
83
90
|
"@types/inquirer": "^9.0.0",
|
|
84
91
|
"@types/normalize-path": "^3.0.0",
|
package/server/db/methods.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { getDb } from './index.js';
|
|
2
2
|
const defaults = {
|
|
3
3
|
AppId: 1,
|
|
4
|
+
AuthorId: 1,
|
|
4
5
|
$created: new Date(),
|
|
5
6
|
$updated: new Date(),
|
|
6
7
|
expires: null,
|
|
@@ -57,6 +58,9 @@ function applyQuery(entity, key, query) {
|
|
|
57
58
|
if (query.eq || query.eq === '') {
|
|
58
59
|
return parsedEntityValue === parseValue(query.eq);
|
|
59
60
|
}
|
|
61
|
+
if (query.eq == null && entity[key] === undefined) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
60
64
|
if (query.ne || query.ne === '') {
|
|
61
65
|
return parsedEntityValue !== parseValue(query.ne);
|
|
62
66
|
}
|
|
@@ -122,7 +126,7 @@ function applyOrder(entities, order) {
|
|
|
122
126
|
}
|
|
123
127
|
}
|
|
124
128
|
function clearEntity(entity) {
|
|
125
|
-
const { AppId, type, ...cleanPayload } = entity;
|
|
129
|
+
const { AppId, AuthorId, type, ...cleanPayload } = entity;
|
|
126
130
|
if (!cleanPayload.expires) {
|
|
127
131
|
delete cleanPayload.expires;
|
|
128
132
|
}
|