Initial commit
This commit is contained in:
3
server/api/apsAuthToken.js
Normal file
3
server/api/apsAuthToken.js
Normal file
@@ -0,0 +1,3 @@
|
||||
import { getViewerToken } from '../utils/aps.js';
|
||||
|
||||
export default defineEventHandler(getViewerToken);
|
||||
25
server/api/models/[urn]/status.js
Normal file
25
server/api/models/[urn]/status.js
Normal file
@@ -0,0 +1,25 @@
|
||||
export default defineEventHandler(async (event) => {
|
||||
const urn = getRouterParam(event, 'urn');
|
||||
const manifest = await getManifest(urn);
|
||||
|
||||
if (!manifest)
|
||||
return { status: 'n/a' };
|
||||
|
||||
let messages = [];
|
||||
if (manifest.derivatives) {
|
||||
for (const derivative of manifest.derivatives) {
|
||||
messages = messages.concat(derivative.messages || []);
|
||||
if (derivative.children) {
|
||||
for (const child of derivative.children) {
|
||||
messages.concat(child.messages || []);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
status: manifest.status,
|
||||
progress: manifest.progress,
|
||||
messages
|
||||
};
|
||||
})
|
||||
37
server/api/models/index.js
Normal file
37
server/api/models/index.js
Normal file
@@ -0,0 +1,37 @@
|
||||
export default defineEventHandler(async (event) => {
|
||||
if (event.method === 'GET') {
|
||||
const objects = await listObjects();
|
||||
return objects.map((o) => ({
|
||||
name: o.objectKey,
|
||||
urn: urnify(o.objectId),
|
||||
}));
|
||||
}
|
||||
|
||||
if (event.method === 'POST') {
|
||||
const formData = await readMultipartFormData(event);
|
||||
if (!formData) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: `formData should not be ${formData}`,
|
||||
})
|
||||
}
|
||||
|
||||
const file = formData[0];
|
||||
|
||||
try {
|
||||
const obj = await uploadObject(file.filename, file.data);
|
||||
await translateObject(urnify(obj.objectId), req.fields['model-zip-entrypoint']);
|
||||
|
||||
return {
|
||||
name: obj.objectKey,
|
||||
urn: urnify(obj.objectId),
|
||||
}
|
||||
} catch (error) {
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: 'Upload file failed',
|
||||
error,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
9
server/middleware/product-rewrite.ts
Normal file
9
server/middleware/product-rewrite.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
export default defineEventHandler((event) => {
|
||||
const originalUrl = event.node.req.url || "";
|
||||
if (originalUrl.startsWith("/product:")) {
|
||||
const rewritten = originalUrl.replace("/product:", "/product/");
|
||||
event.node.req.url = rewritten;
|
||||
event._path = rewritten;
|
||||
}
|
||||
});
|
||||
|
||||
3
server/tsconfig.json
Normal file
3
server/tsconfig.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "../.nuxt/tsconfig.server.json"
|
||||
}
|
||||
101
server/utils/aps.js
Normal file
101
server/utils/aps.js
Normal file
@@ -0,0 +1,101 @@
|
||||
import { AuthenticationClient, Scopes } from '@aps_sdk/authentication';
|
||||
import { ModelDerivativeClient, View, OutputType } from '@aps_sdk/model-derivative';
|
||||
import { OssClient, Region, PolicyKey } from '@aps_sdk/oss';
|
||||
|
||||
const apsClientId = 'PkqB8KlPGekLGKElPSjPhC9C2NGyXMN64QVhPSaqUhV46zEn';
|
||||
const apsClientSecret = 'Jr70CpXFaV2PRd9lux3ZXBKpSMwFsyO6xq1Y7AJy1Q4xcK6nZMLq20KB8SlipC4Z';
|
||||
const apsBucket = `${apsClientId.toLowerCase()}-basic-app`;
|
||||
const authenticationClient = new AuthenticationClient();
|
||||
const ossClient = new OssClient();
|
||||
const modelDerivativeClient = new ModelDerivativeClient();
|
||||
|
||||
async function getInternalToken() {
|
||||
const credentials = await authenticationClient.getTwoLeggedToken(
|
||||
apsClientId,
|
||||
apsClientSecret,
|
||||
[Scopes.DataRead, Scopes.DataCreate, Scopes.DataWrite, Scopes.BucketCreate, Scopes.BucketRead],
|
||||
);
|
||||
return credentials.access_token;
|
||||
}
|
||||
|
||||
export const getViewerToken = async () => {
|
||||
return await authenticationClient.getTwoLeggedToken(apsClientId, apsClientSecret, [
|
||||
Scopes.ViewablesRead,
|
||||
]);
|
||||
};
|
||||
|
||||
export const ensureBucketExists = async (bucketKey) => {
|
||||
const accessToken = await getInternalToken();
|
||||
try {
|
||||
await ossClient.getBucketDetails(bucketKey, { accessToken });
|
||||
} catch (err) {
|
||||
if (err.axiosError.response.status === 404) {
|
||||
await ossClient.createBucket(
|
||||
Region.Us,
|
||||
{ bucketKey: bucketKey, policyKey: PolicyKey.Persistent },
|
||||
{ accessToken },
|
||||
);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const listObjects = async () => {
|
||||
await ensureBucketExists(apsBucket);
|
||||
const accessToken = await getInternalToken();
|
||||
let resp = await ossClient.getObjects(apsBucket, { limit: 64, accessToken });
|
||||
let objects = resp.items;
|
||||
while (resp.next) {
|
||||
const startAt = new URL(resp.next).searchParams.get('startAt');
|
||||
resp = await ossClient.getObjects(apsBucket, { limit: 64, startAt, accessToken });
|
||||
objects = objects.concat(resp.items);
|
||||
}
|
||||
return objects;
|
||||
};
|
||||
|
||||
export const uploadObject = async (objectName, buffer) => {
|
||||
await ensureBucketExists(apsBucket);
|
||||
const accessToken = await getInternalToken();
|
||||
const obj = await ossClient.uploadObject(apsBucket, objectName, buffer, { accessToken });
|
||||
return obj;
|
||||
};
|
||||
|
||||
export const translateObject = async (urn, rootFilename) => {
|
||||
const accessToken = await getInternalToken();
|
||||
const job = await modelDerivativeClient.startJob(
|
||||
{
|
||||
input: {
|
||||
urn,
|
||||
compressedUrn: !!rootFilename,
|
||||
rootFilename,
|
||||
},
|
||||
output: {
|
||||
formats: [
|
||||
{
|
||||
views: [View._2d, View._3d],
|
||||
type: OutputType.Svf2,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{ accessToken },
|
||||
);
|
||||
return job.result;
|
||||
};
|
||||
|
||||
export const getManifest = async (urn) => {
|
||||
const accessToken = await getInternalToken();
|
||||
try {
|
||||
const manifest = await modelDerivativeClient.getManifest(urn, { accessToken });
|
||||
return manifest;
|
||||
} catch (err) {
|
||||
if (err.axiosError.response.status === 404) {
|
||||
return null;
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const urnify = (id) => Buffer.from(id).toString('base64').replace(/=/g, '');
|
||||
Reference in New Issue
Block a user