@slicemachine/init 1.1.10-alpha.5 → 1.1.11-alpha.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/index.js +297 -395
- package/build/index.js.map +1 -1
- package/package.json +4 -11
- package/src/index.ts +42 -33
- package/src/steps/choose-or-create-a-repository.ts +43 -42
- package/src/steps/configure-project.ts +9 -7
- package/src/steps/detect-framework.ts +5 -1
- package/src/steps/install-lib.ts +4 -0
- package/src/steps/loginOrBypass.ts +18 -14
- package/src/steps/sendStarterData.ts +18 -30
- package/src/steps/starters/custom-types.ts +29 -30
- package/src/steps/starters/documents.ts +37 -56
- package/src/steps/starters/prompts.ts +1 -1
- package/src/steps/starters/s3.ts +51 -182
- package/src/steps/starters/slices.ts +55 -42
- package/src/utils/auth/helpers.ts +5 -1
- package/src/utils/auth/index.ts +30 -30
- package/src/utils/client.ts +67 -0
- package/src/utils/create-repo.ts +15 -16
- package/src/utils/fs.ts +18 -0
- package/src/utils/index.ts +16 -0
- package/src/utils/tracker.ts +16 -3
- package/src/utils/validateRepositoryName.ts +44 -0
- package/src/steps/starters/communication.ts +0 -171
- package/src/steps/starters/endpoints.ts +0 -20
- package/src/utils/communication.ts +0 -72
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import fs from "fs";
|
|
3
|
-
import
|
|
3
|
+
import type { AxiosError } from "axios";
|
|
4
|
+
import { Models } from "@slicemachine/core";
|
|
4
5
|
|
|
5
6
|
import * as t from "io-ts";
|
|
6
7
|
import { getOrElseW } from "fp-ts/Either";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
8
|
+
import { InitClient, logs, lsdir, lsfiles } from "../../utils";
|
|
9
|
+
import { PrismicSharedConfigManager } from "@slicemachine/core/build/prismic/SharedConfig";
|
|
10
|
+
import Tracker from "../../utils/tracker";
|
|
9
11
|
|
|
10
12
|
const SignatureFileReader = t.type({
|
|
11
13
|
signature: t.string,
|
|
@@ -23,92 +25,71 @@ export async function readSignatureFile(cwd: string): Promise<SignatureFile> {
|
|
|
23
25
|
});
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
async function
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
.filter((name) => fs.statSync(path.join(dir, name)).isDirectory())
|
|
30
|
-
.map((subdirectory) => path.join(dir, subdirectory));
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
async function lsfiles(dir: string): Promise<Array<string>> {
|
|
35
|
-
return fs.promises.readdir(dir).then((dirs) => {
|
|
36
|
-
return dirs
|
|
37
|
-
.filter((name) => fs.statSync(path.join(dir, name)).isFile())
|
|
38
|
-
.map((file) => path.join(dir, file));
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export async function readDocuments(cwd: string) {
|
|
28
|
+
export async function readDocuments(
|
|
29
|
+
cwd: string
|
|
30
|
+
): Promise<Record<string, unknown>> {
|
|
43
31
|
const documentDir = path.join(cwd, "documents");
|
|
44
32
|
const dirs = await lsdir(documentDir);
|
|
45
33
|
|
|
46
34
|
const files = (await Promise.all(dirs.map((dir) => lsfiles(dir)))).flat();
|
|
47
35
|
|
|
48
36
|
const documentObj = files.reduce<Record<string, unknown>>((acc, file) => {
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
37
|
+
const filename: string = path.parse(file).name;
|
|
38
|
+
const fileContent: string = fs.readFileSync(file, "utf-8");
|
|
39
|
+
const json = JSON.parse(fileContent) as Record<string, unknown>;
|
|
40
|
+
|
|
41
|
+
return { ...acc, [filename]: json };
|
|
53
42
|
}, {});
|
|
54
43
|
|
|
55
|
-
return
|
|
44
|
+
return documentObj;
|
|
56
45
|
}
|
|
57
46
|
|
|
58
|
-
export
|
|
59
|
-
|
|
60
|
-
cookies: string,
|
|
61
|
-
base: string,
|
|
47
|
+
export async function sendDocuments(
|
|
48
|
+
client: InitClient,
|
|
62
49
|
cwd: string
|
|
63
|
-
): Promise<boolean>
|
|
50
|
+
): Promise<boolean> {
|
|
64
51
|
const pathToDocuments = path.join(cwd, "documents");
|
|
65
52
|
const pathToSignatureFile = path.join(pathToDocuments, "index.json");
|
|
66
53
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
54
|
+
// Without the signature, we can't push documents to Prismic.
|
|
55
|
+
if (!fs.existsSync(pathToSignatureFile)) return Promise.resolve(false);
|
|
70
56
|
|
|
71
57
|
const signatureObj = await readSignatureFile(cwd);
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
const payload = {
|
|
75
|
-
signature: signatureObj.signature,
|
|
76
|
-
documents: documentsStr,
|
|
77
|
-
};
|
|
58
|
+
const documents: Record<string, unknown> = await readDocuments(cwd);
|
|
78
59
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
prismicUrl.pathname = "starter/documents";
|
|
82
|
-
const endpointURL = prismicUrl.toString();
|
|
60
|
+
// No documents to push
|
|
61
|
+
if (Object.keys(documents).length === 0) return Promise.resolve(false);
|
|
83
62
|
|
|
84
63
|
const spinner = logs.spinner("Pushing existing documents to your repository");
|
|
85
64
|
spinner.start();
|
|
86
65
|
|
|
87
|
-
return
|
|
88
|
-
.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
})
|
|
66
|
+
return client
|
|
67
|
+
.pushDocuments(
|
|
68
|
+
signatureObj.signature,
|
|
69
|
+
documents,
|
|
70
|
+
PrismicSharedConfigManager.get().cookies
|
|
71
|
+
)
|
|
94
72
|
.then(() => {
|
|
95
73
|
spinner.succeed();
|
|
96
74
|
fs.rmSync(pathToDocuments, { recursive: true, force: true });
|
|
97
75
|
return true;
|
|
98
76
|
})
|
|
99
|
-
.catch((e: AxiosError) => {
|
|
77
|
+
.catch(async (e: AxiosError) => {
|
|
100
78
|
spinner.fail();
|
|
101
79
|
if (e.response?.data === "Repository should not contain documents") {
|
|
102
80
|
logs.writeError(
|
|
103
81
|
"The selected repository is not empty, documents cannot be uploaded. Please choose an empty repository or delete the documents contained in your repository."
|
|
104
82
|
);
|
|
105
83
|
} else {
|
|
106
|
-
|
|
107
|
-
"
|
|
108
|
-
e
|
|
84
|
+
logs.writeError(
|
|
85
|
+
"Sending documents failed, please try again. If the problem persists, contact us."
|
|
109
86
|
);
|
|
87
|
+
logs.writeError(`Full error: ${e.code || 500} - ${e.message}`);
|
|
110
88
|
}
|
|
111
|
-
|
|
89
|
+
await Tracker.get().trackInitEndFail(
|
|
90
|
+
Models.Frameworks.none,
|
|
91
|
+
"Failed to push documents"
|
|
92
|
+
);
|
|
112
93
|
process.exit(1);
|
|
113
94
|
});
|
|
114
|
-
}
|
|
95
|
+
}
|
|
@@ -22,7 +22,7 @@ export async function promptToPushCustomTypes(): Promise<boolean> {
|
|
|
22
22
|
name: "pushCustomTypes",
|
|
23
23
|
default: false,
|
|
24
24
|
message:
|
|
25
|
-
"Your repository already contains Custom Types. Do you want to continue pushing your local
|
|
25
|
+
"Your repository already contains Custom Types. Do you want to continue pushing your local Custom Types?",
|
|
26
26
|
},
|
|
27
27
|
])
|
|
28
28
|
.then((res) => res.pushCustomTypes);
|
package/src/steps/starters/s3.ts
CHANGED
|
@@ -1,201 +1,70 @@
|
|
|
1
|
-
import
|
|
2
|
-
import axios from "axios";
|
|
3
|
-
import mime from "mime";
|
|
4
|
-
import snakeCase from "lodash.snakecase";
|
|
5
|
-
import path from "path";
|
|
6
|
-
import FormData from "form-data";
|
|
7
|
-
import uniqid from "uniqid";
|
|
8
|
-
import { logs } from "../../utils";
|
|
1
|
+
import { InitClient } from "../../utils";
|
|
9
2
|
import {
|
|
10
3
|
Component,
|
|
11
4
|
ComponentInfo,
|
|
12
5
|
VariationSM,
|
|
13
6
|
SliceSM,
|
|
14
7
|
} from "@slicemachine/core/build/models";
|
|
8
|
+
import { Acl, ClientError } from "@slicemachine/client";
|
|
9
|
+
import { writeError } from "../../utils/logs";
|
|
15
10
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
export async function createAcl(
|
|
26
|
-
address: string,
|
|
27
|
-
repository: string,
|
|
28
|
-
authorization: string
|
|
29
|
-
): Promise<ALC> {
|
|
30
|
-
return axios
|
|
31
|
-
.get<ALC>(address + "create", {
|
|
32
|
-
headers: {
|
|
33
|
-
repository,
|
|
34
|
-
Authorization: `Bearer ${authorization}`,
|
|
35
|
-
"User-Agent": "slice-machine",
|
|
36
|
-
},
|
|
37
|
-
})
|
|
38
|
-
.then((res) => res.data);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async function createFormForS3(
|
|
42
|
-
key: string,
|
|
43
|
-
filename: string,
|
|
44
|
-
filePath: string,
|
|
45
|
-
acl: ALC
|
|
46
|
-
): Promise<FormData | null> {
|
|
47
|
-
const form = new FormData();
|
|
48
|
-
Object.entries(acl.values.fields).forEach(([k, value]) => {
|
|
49
|
-
form.append(k, value);
|
|
50
|
-
});
|
|
51
|
-
form.append("key", key);
|
|
52
|
-
const contentType = mime.getType(filePath);
|
|
53
|
-
contentType && form.append("Content-Type", contentType);
|
|
54
|
-
|
|
55
|
-
return fs.promises
|
|
56
|
-
.readFile(filePath)
|
|
57
|
-
.then((file) => {
|
|
58
|
-
form.append("file", file, { filename });
|
|
59
|
-
return form;
|
|
60
|
-
})
|
|
61
|
-
.catch(() => {
|
|
62
|
-
logs.writeError(`Error reading preview image: ${filename}`);
|
|
63
|
-
return null;
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function createS3Key(
|
|
68
|
-
repository: string,
|
|
69
|
-
sliceName: string,
|
|
70
|
-
variationId: string,
|
|
71
|
-
filename: string
|
|
72
|
-
): string {
|
|
73
|
-
return `${repository}/shared-slices/${snakeCase(sliceName)}/${snakeCase(
|
|
74
|
-
variationId
|
|
75
|
-
)}-${uniqid()}/${filename}`;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
async function sendVariationPreviewToS3(
|
|
79
|
-
acl: ALC,
|
|
80
|
-
repository: string,
|
|
81
|
-
sliceName: string,
|
|
82
|
-
variationId: string,
|
|
83
|
-
filePath: string
|
|
84
|
-
): Promise<string | null> {
|
|
85
|
-
const filename = path.basename(filePath);
|
|
86
|
-
const key = createS3Key(repository, sliceName, variationId, filename);
|
|
87
|
-
const form = await createFormForS3(key, filename, filePath, acl);
|
|
88
|
-
if (form === null) return null;
|
|
89
|
-
if (form.hasKnownLength() === false) {
|
|
90
|
-
logs.writeError(
|
|
91
|
-
`[slice/push] An error occurred while uploading preview image ${filePath} as length in unknown`
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const errorMessage = `[slice/push] An error occurred while uploading preview images for ${sliceName}-${variationId} - please contact support`;
|
|
11
|
+
async function updateVariationWithScreenshot(
|
|
12
|
+
client: InitClient,
|
|
13
|
+
acl: Acl,
|
|
14
|
+
screenshotPaths: ComponentInfo["screenshotPaths"],
|
|
15
|
+
sliceName: SliceSM["id"],
|
|
16
|
+
variation: VariationSM
|
|
17
|
+
): Promise<VariationSM> {
|
|
18
|
+
const screenshot = screenshotPaths[variation.id];
|
|
19
|
+
if (!screenshot || !screenshot.path) return Promise.resolve(variation);
|
|
96
20
|
|
|
97
|
-
return
|
|
98
|
-
.
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
21
|
+
return client
|
|
22
|
+
.uploadScreenshot({
|
|
23
|
+
acl,
|
|
24
|
+
sliceName,
|
|
25
|
+
variationId: variation.id,
|
|
26
|
+
filePath: screenshot.path,
|
|
103
27
|
})
|
|
104
|
-
.then((
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
} else {
|
|
110
|
-
return `${acl.imgixEndpoint}/${key}`;
|
|
111
|
-
}
|
|
28
|
+
.then((screenshotUrl) => {
|
|
29
|
+
return {
|
|
30
|
+
...variation,
|
|
31
|
+
imageUrl: screenshotUrl,
|
|
32
|
+
};
|
|
112
33
|
})
|
|
113
|
-
.catch((
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
} else {
|
|
120
|
-
logs.writeError(String(err));
|
|
121
|
-
}
|
|
122
|
-
return null;
|
|
34
|
+
.catch((error: ClientError) => {
|
|
35
|
+
writeError(
|
|
36
|
+
`Couldn't upload screenshot slice: ${sliceName} - variation: ${variation.id}`
|
|
37
|
+
);
|
|
38
|
+
writeError(error.message, "Full error:");
|
|
39
|
+
return variation;
|
|
123
40
|
});
|
|
124
41
|
}
|
|
125
42
|
|
|
126
|
-
async function
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
variation: VariationSM
|
|
132
|
-
): Promise<VariationSM> {
|
|
133
|
-
const imageUrl = await sendVariationPreviewToS3(
|
|
134
|
-
acl,
|
|
135
|
-
repository,
|
|
136
|
-
modelId,
|
|
137
|
-
variation.id,
|
|
138
|
-
pathToScreenShot
|
|
139
|
-
);
|
|
140
|
-
if (!imageUrl) return variation;
|
|
141
|
-
|
|
142
|
-
return {
|
|
143
|
-
...variation,
|
|
144
|
-
imageUrl,
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
async function addImageUrlsToVariations(
|
|
149
|
-
acl: ALC,
|
|
150
|
-
repository: string,
|
|
151
|
-
modelId: string,
|
|
152
|
-
screenshotPaths: ComponentInfo["screenshotPaths"],
|
|
153
|
-
variations: Array<VariationSM>
|
|
154
|
-
): Promise<Array<VariationSM>> {
|
|
43
|
+
export async function updateSlicesWithScreenshots(
|
|
44
|
+
client: InitClient,
|
|
45
|
+
acl: Acl,
|
|
46
|
+
components: Array<Component>
|
|
47
|
+
): Promise<Array<SliceSM>> {
|
|
155
48
|
return Promise.all(
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
if (!screenshot || !screenshot.path) return variation;
|
|
49
|
+
components.map(async (component) => {
|
|
50
|
+
const { screenshotPaths, model } = component;
|
|
159
51
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
52
|
+
const variationsUpdated: VariationSM[] = await Promise.all(
|
|
53
|
+
model.variations.map(async (variation) =>
|
|
54
|
+
updateVariationWithScreenshot(
|
|
55
|
+
client,
|
|
56
|
+
acl,
|
|
57
|
+
screenshotPaths,
|
|
58
|
+
model.id,
|
|
59
|
+
variation
|
|
60
|
+
)
|
|
61
|
+
)
|
|
166
62
|
);
|
|
167
|
-
})
|
|
168
|
-
);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
async function maybeUpdateModelVariationsWithImageUrl(
|
|
172
|
-
acl: ALC,
|
|
173
|
-
repository: string,
|
|
174
|
-
component: Component
|
|
175
|
-
): Promise<SliceSM> {
|
|
176
|
-
const { screenshotPaths, model } = component;
|
|
177
|
-
const variations = await addImageUrlsToVariations(
|
|
178
|
-
acl,
|
|
179
|
-
repository,
|
|
180
|
-
model.id,
|
|
181
|
-
screenshotPaths,
|
|
182
|
-
model.variations
|
|
183
|
-
);
|
|
184
|
-
|
|
185
|
-
return {
|
|
186
|
-
...model,
|
|
187
|
-
variations,
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
63
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
)
|
|
196
|
-
return Promise.all(
|
|
197
|
-
components.map(async (component) =>
|
|
198
|
-
maybeUpdateModelVariationsWithImageUrl(acl, repository, component)
|
|
199
|
-
)
|
|
64
|
+
return {
|
|
65
|
+
...model,
|
|
66
|
+
variations: variationsUpdated,
|
|
67
|
+
};
|
|
68
|
+
})
|
|
200
69
|
);
|
|
201
70
|
}
|
|
@@ -1,34 +1,32 @@
|
|
|
1
|
-
import { Component } from "@slicemachine/core/build/models";
|
|
1
|
+
import { Component, Manifest, Slices } from "@slicemachine/core/build/models";
|
|
2
|
+
import { Acl, ClientError } from "@slicemachine/client";
|
|
3
|
+
import { InitClient, logs } from "../../utils";
|
|
2
4
|
import * as Libraries from "@slicemachine/core/build/libraries";
|
|
3
|
-
import { logs } from "../../utils";
|
|
4
|
-
import { getRemoteSliceIds, sendManyModelsToPrismic } from "./communication";
|
|
5
|
-
import { getEndpointsFromBase } from "./endpoints";
|
|
6
5
|
import { promptToPushSlices } from "./prompts";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
export async function sendSlicesFromStarter(
|
|
10
|
-
base: string,
|
|
11
|
-
repository: string,
|
|
12
|
-
authorization: string,
|
|
13
|
-
libraryPaths: Array<string>,
|
|
14
|
-
cwd: string
|
|
15
|
-
) {
|
|
16
|
-
const endpoints = getEndpointsFromBase(base);
|
|
17
|
-
const libraries = Libraries.libraries(cwd, libraryPaths);
|
|
18
|
-
|
|
19
|
-
if (libraries.length === 0) return Promise.resolve(false);
|
|
20
|
-
|
|
21
|
-
const remoteSlices = await getRemoteSliceIds(
|
|
22
|
-
endpoints.Models,
|
|
23
|
-
repository,
|
|
24
|
-
authorization
|
|
25
|
-
);
|
|
6
|
+
import { updateSlicesWithScreenshots } from "./s3";
|
|
7
|
+
import { writeError } from "../../utils/logs";
|
|
26
8
|
|
|
27
|
-
|
|
28
|
-
|
|
9
|
+
export async function sendSlices(
|
|
10
|
+
client: InitClient,
|
|
11
|
+
cwd: string,
|
|
12
|
+
manifest: Manifest
|
|
13
|
+
): Promise<boolean> {
|
|
14
|
+
if (!manifest.libraries) return Promise.resolve(false); // No libraries defined
|
|
29
15
|
|
|
30
|
-
|
|
16
|
+
const libraries = Libraries.libraries(cwd, manifest.libraries);
|
|
17
|
+
const components = libraries.reduce<Array<Component>>((acc, lib) => {
|
|
18
|
+
return [...acc, ...lib.components];
|
|
19
|
+
}, []);
|
|
20
|
+
|
|
21
|
+
if (components.length === 0) return Promise.resolve(false); // No slices to send found in the libraries
|
|
31
22
|
|
|
23
|
+
const remoteSlicesIds: string[] = await client
|
|
24
|
+
.getSlices()
|
|
25
|
+
.then((slices) => slices.map((slice) => slice.id));
|
|
26
|
+
|
|
27
|
+
// If the repository already has Slices, ask the user to confirm.
|
|
28
|
+
if (remoteSlicesIds.length) {
|
|
29
|
+
const pushAnyway = await promptToPushSlices();
|
|
32
30
|
if (pushAnyway === false) return Promise.resolve(true);
|
|
33
31
|
}
|
|
34
32
|
|
|
@@ -37,25 +35,40 @@ export async function sendSlicesFromStarter(
|
|
|
37
35
|
);
|
|
38
36
|
spinner.start();
|
|
39
37
|
|
|
40
|
-
const acl = await
|
|
38
|
+
const acl: Acl | null = await client
|
|
39
|
+
.createAcl()
|
|
40
|
+
.catch((error: ClientError) => {
|
|
41
|
+
writeError(
|
|
42
|
+
"Uploading screenshots for your slices failed, please contact us."
|
|
43
|
+
);
|
|
44
|
+
writeError(error.message, "Full error:");
|
|
45
|
+
return null;
|
|
46
|
+
});
|
|
41
47
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
// If the acl failed to be created, don't mind the screenshots.
|
|
49
|
+
const models = acl
|
|
50
|
+
? await updateSlicesWithScreenshots(client, acl, components)
|
|
51
|
+
: components.map((component) => component.model);
|
|
45
52
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
components
|
|
50
|
-
);
|
|
53
|
+
await Promise.all(
|
|
54
|
+
models.map(async (model) => {
|
|
55
|
+
const slice = Slices.fromSM(model);
|
|
51
56
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
const promise = remoteSlicesIds.includes(slice.id)
|
|
58
|
+
? client.updateSlice(slice)
|
|
59
|
+
: client.insertSlice(slice);
|
|
60
|
+
|
|
61
|
+
return promise.catch((error: ClientError) => {
|
|
62
|
+
logs.writeError(`Sending slice ${model.id} - ${error.message}`);
|
|
63
|
+
|
|
64
|
+
// throwing the error again to stop the Promise.all
|
|
65
|
+
throw error;
|
|
66
|
+
});
|
|
67
|
+
})
|
|
68
|
+
).catch(() => {
|
|
69
|
+
// the error about the slice that failed to be pushed should be in the terminal already.
|
|
70
|
+
process.exit(1);
|
|
71
|
+
});
|
|
59
72
|
|
|
60
73
|
spinner.succeed();
|
|
61
74
|
return Promise.resolve(true);
|
|
@@ -81,13 +81,17 @@ const authenticationHandler =
|
|
|
81
81
|
};
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
+
function stripTrailingSlash(str: string) {
|
|
85
|
+
return str.endsWith("/") ? str.slice(0, -1) : str;
|
|
86
|
+
}
|
|
87
|
+
|
|
84
88
|
function buildServer(base: string, port: number, host: string): hapi.Server {
|
|
85
89
|
const server = hapi.server({
|
|
86
90
|
port,
|
|
87
91
|
host,
|
|
88
92
|
routes: {
|
|
89
93
|
cors: {
|
|
90
|
-
origin: [base],
|
|
94
|
+
origin: [stripTrailingSlash(base)],
|
|
91
95
|
headers: ["Origin", "X-Requested-With", "Content-Type", "Accept"],
|
|
92
96
|
},
|
|
93
97
|
},
|
package/src/utils/auth/index.ts
CHANGED
|
@@ -1,26 +1,30 @@
|
|
|
1
|
-
import { Utils
|
|
1
|
+
import { Utils } from "@slicemachine/core";
|
|
2
2
|
import { startServerAndOpenBrowser } from "./helpers";
|
|
3
3
|
import {
|
|
4
|
-
Communication,
|
|
5
4
|
Endpoints,
|
|
6
5
|
PrismicSharedConfigManager,
|
|
7
6
|
} from "@slicemachine/core/build/prismic";
|
|
7
|
+
import { InitClient } from "../client";
|
|
8
8
|
|
|
9
9
|
async function startAuth({
|
|
10
|
-
|
|
10
|
+
client,
|
|
11
11
|
url,
|
|
12
12
|
action,
|
|
13
13
|
}: {
|
|
14
|
-
|
|
14
|
+
client: InitClient;
|
|
15
15
|
url: string;
|
|
16
16
|
action: "signup" | "login";
|
|
17
17
|
}): Promise<void> {
|
|
18
|
-
const { onLoginFail } = await startServerAndOpenBrowser(
|
|
18
|
+
const { onLoginFail } = await startServerAndOpenBrowser(
|
|
19
|
+
url,
|
|
20
|
+
action,
|
|
21
|
+
client.apisEndpoints.Wroom
|
|
22
|
+
);
|
|
19
23
|
try {
|
|
20
24
|
// We wait 3 minutes before timeout
|
|
21
|
-
await Utils.Poll.startPolling<
|
|
22
|
-
() => Auth.validateSession(
|
|
23
|
-
(
|
|
25
|
+
await Utils.Poll.startPolling<boolean, boolean>(
|
|
26
|
+
() => Auth.validateSession(client),
|
|
27
|
+
(isSessionValid): isSessionValid is boolean => isSessionValid == true,
|
|
24
28
|
3000,
|
|
25
29
|
60
|
|
26
30
|
);
|
|
@@ -31,33 +35,29 @@ async function startAuth({
|
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
export const Auth = {
|
|
34
|
-
login: async (
|
|
35
|
-
const endpoints = Endpoints.buildEndpoints(
|
|
38
|
+
login: async (client: InitClient): Promise<void> => {
|
|
39
|
+
const endpoints = Endpoints.buildEndpoints(client.apisEndpoints.Wroom);
|
|
36
40
|
return startAuth({
|
|
37
|
-
|
|
41
|
+
client,
|
|
38
42
|
url: endpoints.Dashboard.cliLogin,
|
|
39
43
|
action: "login",
|
|
40
44
|
});
|
|
41
45
|
},
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
return startAuth({
|
|
45
|
-
base,
|
|
46
|
-
url: endpoints.Dashboard.cliSignup,
|
|
47
|
-
action: "signup",
|
|
48
|
-
});
|
|
49
|
-
},
|
|
50
|
-
logout: (): void => PrismicSharedConfigManager.remove(),
|
|
51
|
-
validateSession: async (
|
|
52
|
-
requiredBase: string
|
|
53
|
-
): Promise<Models.UserInfo | null> => {
|
|
54
|
-
const config = PrismicSharedConfigManager.get();
|
|
46
|
+
validateSession: async (client: InitClient): Promise<boolean> => {
|
|
47
|
+
const authToken = PrismicSharedConfigManager.getAuth();
|
|
55
48
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
() =>
|
|
61
|
-
|
|
49
|
+
// verify token is by retrieving the profile, update the config if need be.
|
|
50
|
+
return client
|
|
51
|
+
.updateAuthenticationToken(authToken)
|
|
52
|
+
.profile()
|
|
53
|
+
.then((userProfile) => {
|
|
54
|
+
// settings shortId and IntercomHash as we switch between dev and prod.
|
|
55
|
+
PrismicSharedConfigManager.setProperties({
|
|
56
|
+
shortId: userProfile.shortId,
|
|
57
|
+
intercomHash: userProfile.intercomHash,
|
|
58
|
+
});
|
|
59
|
+
return true;
|
|
60
|
+
})
|
|
61
|
+
.catch(() => false);
|
|
62
62
|
},
|
|
63
63
|
};
|