nuxt-studio 0.0.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 +241 -0
- package/dist/app/main.d.ts +342 -0
- package/dist/app/main.js +38597 -0
- package/dist/app/mdc-import-BDMct_Gn.js +4 -0
- package/dist/app/service-worker.d.ts +3 -0
- package/dist/app/service-worker.js +118 -0
- package/dist/app/shared-D04791PA.js +25754 -0
- package/dist/app/shared-DI6F-ifc.js +25774 -0
- package/dist/app/shared-R5zYJ3Dl.js +25803 -0
- package/dist/app/shared.d.ts +22 -0
- package/dist/app/shared.js +6 -0
- package/dist/app/utils-DI6F-ifc.js +25774 -0
- package/dist/app/utils.d.ts +22 -0
- package/dist/app/utils.js +6 -0
- package/dist/module/module.d.mts +68 -0
- package/dist/module/module.json +10 -0
- package/dist/module/module.mjs +185 -0
- package/dist/module/runtime/composables/useMeta.d.ts +6 -0
- package/dist/module/runtime/composables/useMeta.js +17 -0
- package/dist/module/runtime/host.d.ts +2 -0
- package/dist/module/runtime/host.dev.d.ts +2 -0
- package/dist/module/runtime/host.dev.js +46 -0
- package/dist/module/runtime/host.js +257 -0
- package/dist/module/runtime/plugins/studio.client.d.ts +2 -0
- package/dist/module/runtime/plugins/studio.client.dev.d.ts +2 -0
- package/dist/module/runtime/plugins/studio.client.dev.js +23 -0
- package/dist/module/runtime/plugins/studio.client.js +11 -0
- package/dist/module/runtime/server/routes/admin.d.ts +2 -0
- package/dist/module/runtime/server/routes/admin.js +192 -0
- package/dist/module/runtime/server/routes/auth/github.get.d.ts +53 -0
- package/dist/module/runtime/server/routes/auth/github.get.js +155 -0
- package/dist/module/runtime/server/routes/auth/google.get.d.ts +2 -0
- package/dist/module/runtime/server/routes/auth/google.get.js +13 -0
- package/dist/module/runtime/server/routes/auth/session.delete.d.ts +4 -0
- package/dist/module/runtime/server/routes/auth/session.delete.js +10 -0
- package/dist/module/runtime/server/routes/auth/session.get.d.ts +4 -0
- package/dist/module/runtime/server/routes/auth/session.get.js +12 -0
- package/dist/module/runtime/server/routes/dev/content/[...path].d.ts +2 -0
- package/dist/module/runtime/server/routes/dev/content/[...path].js +57 -0
- package/dist/module/runtime/server/routes/dev/public/[...path].d.ts +8 -0
- package/dist/module/runtime/server/routes/dev/public/[...path].js +61 -0
- package/dist/module/runtime/server/routes/meta.d.ts +17 -0
- package/dist/module/runtime/server/routes/meta.js +39 -0
- package/dist/module/runtime/server/routes/sw.d.ts +2 -0
- package/dist/module/runtime/server/routes/sw.js +6 -0
- package/dist/module/runtime/utils/activation.d.ts +2 -0
- package/dist/module/runtime/utils/activation.js +23 -0
- package/dist/module/runtime/utils/collection.d.ts +22 -0
- package/dist/module/runtime/utils/collection.js +154 -0
- package/dist/module/runtime/utils/ensure.d.ts +1 -0
- package/dist/module/runtime/utils/ensure.js +22 -0
- package/dist/module/runtime/utils/object.d.ts +3 -0
- package/dist/module/runtime/utils/object.js +3 -0
- package/dist/module/runtime/utils/path-meta.d.ts +50 -0
- package/dist/module/runtime/utils/path-meta.js +49 -0
- package/dist/module/types.d.mts +7 -0
- package/package.json +100 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { CollectionItemBase } from '@nuxt/content';
|
|
2
|
+
|
|
3
|
+
declare interface BaseItem {
|
|
4
|
+
id: string;
|
|
5
|
+
extension: string;
|
|
6
|
+
stem: string;
|
|
7
|
+
path?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
declare interface DatabaseItem extends CollectionItemBase, BaseItem {
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export declare function generateContentFromDocument(document: DatabaseItem): Promise<string | null>;
|
|
15
|
+
|
|
16
|
+
export declare function generateDocumentFromContent(id: string, content: string): Promise<DatabaseItem | null>;
|
|
17
|
+
|
|
18
|
+
export declare function removeReservedKeysFromDocument(document: DatabaseItem): {
|
|
19
|
+
[k: string]: unknown;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export { }
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
+
|
|
3
|
+
interface ModuleOptions {
|
|
4
|
+
/**
|
|
5
|
+
* The route to access the studio login page.
|
|
6
|
+
* @default '/_studio'
|
|
7
|
+
*/
|
|
8
|
+
route?: string;
|
|
9
|
+
/**
|
|
10
|
+
* The authentication settings for studio.
|
|
11
|
+
*/
|
|
12
|
+
auth?: {
|
|
13
|
+
/**
|
|
14
|
+
* The GitHub OAuth credentials.
|
|
15
|
+
*/
|
|
16
|
+
github?: {
|
|
17
|
+
/**
|
|
18
|
+
* The GitHub OAuth client ID.
|
|
19
|
+
* @default process.env.STUDIO_GITHUB_CLIENT_ID
|
|
20
|
+
*/
|
|
21
|
+
clientId?: string;
|
|
22
|
+
/**
|
|
23
|
+
* The GitHub OAuth client secret.
|
|
24
|
+
* @default process.env.STUDIO_GITHUB_CLIENT_SECRET
|
|
25
|
+
*/
|
|
26
|
+
clientSecret?: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* The git repository information to connect to.
|
|
31
|
+
*/
|
|
32
|
+
repository?: {
|
|
33
|
+
/**
|
|
34
|
+
* The provider to use for the git repository.
|
|
35
|
+
* @default 'github'
|
|
36
|
+
*/
|
|
37
|
+
provider?: 'github';
|
|
38
|
+
/**
|
|
39
|
+
* The owner of the git repository.
|
|
40
|
+
*/
|
|
41
|
+
owner: string;
|
|
42
|
+
/**
|
|
43
|
+
* The repository name.
|
|
44
|
+
*/
|
|
45
|
+
repo: string;
|
|
46
|
+
/**
|
|
47
|
+
* The branch to use for the git repository.
|
|
48
|
+
* @default 'main'
|
|
49
|
+
*/
|
|
50
|
+
branch?: string;
|
|
51
|
+
/**
|
|
52
|
+
* The root directory to use for the git repository.
|
|
53
|
+
* @default ''
|
|
54
|
+
*/
|
|
55
|
+
rootDir?: string;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Enable Nuxt Studio to edit content and media files on your filesystem.
|
|
59
|
+
* Currently experimental.
|
|
60
|
+
* @experimental
|
|
61
|
+
*/
|
|
62
|
+
development?: {
|
|
63
|
+
sync?: boolean;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
67
|
+
|
|
68
|
+
export { _default as default };
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { useLogger, defineNuxtModule, createResolver, addPlugin, extendViteConfig, addServerHandler, addVitePlugin, addTemplate } from '@nuxt/kit';
|
|
2
|
+
import { createHash } from 'node:crypto';
|
|
3
|
+
import { defu } from 'defu';
|
|
4
|
+
import { resolve } from 'node:path';
|
|
5
|
+
import fsDriver from 'unstorage/drivers/fs';
|
|
6
|
+
import { createStorage } from 'unstorage';
|
|
7
|
+
|
|
8
|
+
async function getAssetsStorageDevTemplate(_assetsStorage, _nuxt) {
|
|
9
|
+
return [
|
|
10
|
+
"import { createStorage } from 'unstorage'",
|
|
11
|
+
"import httpDriver from 'unstorage/drivers/http'",
|
|
12
|
+
"",
|
|
13
|
+
`const storage = createStorage({ driver: httpDriver({ base: '/__nuxt_studio/dev/public' }) })`,
|
|
14
|
+
"export const publicAssetsStorage = storage"
|
|
15
|
+
].join("\n");
|
|
16
|
+
}
|
|
17
|
+
async function getAssetsStorageTemplate(assetsStorage, _nuxt) {
|
|
18
|
+
const keys = await assetsStorage.getKeys();
|
|
19
|
+
return [
|
|
20
|
+
"import { createStorage } from 'unstorage'",
|
|
21
|
+
"const storage = createStorage({})",
|
|
22
|
+
"",
|
|
23
|
+
...keys.map((key) => {
|
|
24
|
+
const value = {
|
|
25
|
+
id: `public-assets/${key.replace(/:/g, "/")}`,
|
|
26
|
+
extension: key.split(".").pop(),
|
|
27
|
+
stem: key.split(".").join("."),
|
|
28
|
+
path: "/" + key.replace(/:/g, "/")
|
|
29
|
+
};
|
|
30
|
+
return `storage.setItem('${value.id}', ${JSON.stringify(value)})`;
|
|
31
|
+
}),
|
|
32
|
+
"",
|
|
33
|
+
"export const publicAssetsStorage = storage"
|
|
34
|
+
].join("\n");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const version = "0.0.0";
|
|
38
|
+
|
|
39
|
+
const logger = useLogger("nuxt-studio");
|
|
40
|
+
const module = defineNuxtModule({
|
|
41
|
+
meta: {
|
|
42
|
+
name: "nuxt-studio",
|
|
43
|
+
configKey: "studio",
|
|
44
|
+
version,
|
|
45
|
+
docs: "https://content.nuxt.com/studio"
|
|
46
|
+
},
|
|
47
|
+
defaults: {
|
|
48
|
+
route: "/_studio",
|
|
49
|
+
repository: {
|
|
50
|
+
provider: "github",
|
|
51
|
+
owner: "",
|
|
52
|
+
repo: "",
|
|
53
|
+
branch: "main",
|
|
54
|
+
rootDir: ""
|
|
55
|
+
},
|
|
56
|
+
auth: {
|
|
57
|
+
github: {
|
|
58
|
+
clientId: process.env.STUDIO_GITHUB_CLIENT_ID,
|
|
59
|
+
clientSecret: process.env.STUDIO_GITHUB_CLIENT_SECRET
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
development: {
|
|
63
|
+
sync: false
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
async setup(options, nuxt) {
|
|
67
|
+
const resolver = createResolver(import.meta.url);
|
|
68
|
+
const runtime = (...args) => resolver.resolve("./runtime", ...args);
|
|
69
|
+
if (!nuxt.options.dev) {
|
|
70
|
+
options.development.sync = false;
|
|
71
|
+
}
|
|
72
|
+
if (!nuxt.options.dev && !nuxt.options._prepare) {
|
|
73
|
+
if (!options.auth?.github?.clientId && !options.auth?.github?.clientSecret) {
|
|
74
|
+
logger.warn([
|
|
75
|
+
"Nuxt Content Studio relies on GitHub OAuth to authenticate users.",
|
|
76
|
+
"Please set the `STUDIO_GITHUB_CLIENT_ID` and `STUDIO_GITHUB_CLIENT_SECRET` environment variables."
|
|
77
|
+
].join(" "));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
nuxt.options.experimental = nuxt.options.experimental || {};
|
|
81
|
+
nuxt.options.experimental.checkOutdatedBuildInterval = 1e3 * 30;
|
|
82
|
+
nuxt.options.runtimeConfig.public.studio = {
|
|
83
|
+
route: options.route,
|
|
84
|
+
development: {
|
|
85
|
+
sync: Boolean(options.development.sync),
|
|
86
|
+
server: process.env.STUDIO_DEV_SERVER
|
|
87
|
+
},
|
|
88
|
+
// @ts-expect-error Autogenerated type does not match with options
|
|
89
|
+
repository: options.repository
|
|
90
|
+
};
|
|
91
|
+
nuxt.options.runtimeConfig.studio = {
|
|
92
|
+
auth: {
|
|
93
|
+
sessionSecret: createHash("md5").update([
|
|
94
|
+
options.auth?.github?.clientId,
|
|
95
|
+
options.auth?.github?.clientSecret
|
|
96
|
+
].join("")).digest("hex"),
|
|
97
|
+
// @ts-expect-error todo fix github type issue
|
|
98
|
+
github: options.auth?.github
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
addPlugin(process.env.STUDIO_DEV_SERVER ? runtime("./plugins/studio.client.dev") : runtime("./plugins/studio.client"));
|
|
102
|
+
nuxt.options.vite = defu(nuxt.options.vite, {
|
|
103
|
+
vue: {
|
|
104
|
+
template: {
|
|
105
|
+
compilerOptions: {
|
|
106
|
+
isCustomElement: (tag) => tag === "nuxt-studio"
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
extendViteConfig((config) => {
|
|
112
|
+
config.define ||= {};
|
|
113
|
+
config.define["import.meta.preview"] = true;
|
|
114
|
+
config.optimizeDeps ||= {};
|
|
115
|
+
config.optimizeDeps.include = [
|
|
116
|
+
...config.optimizeDeps.include || [],
|
|
117
|
+
"debug",
|
|
118
|
+
"extend"
|
|
119
|
+
];
|
|
120
|
+
});
|
|
121
|
+
if (options.development.sync) {
|
|
122
|
+
nuxt.options.nitro.storage = {
|
|
123
|
+
...nuxt.options.nitro.storage,
|
|
124
|
+
nuxt_studio_content: {
|
|
125
|
+
driver: "fs",
|
|
126
|
+
base: resolve(nuxt.options.rootDir, "content")
|
|
127
|
+
},
|
|
128
|
+
nuxt_studio_public_assets: {
|
|
129
|
+
driver: "fs",
|
|
130
|
+
base: resolve(nuxt.options.srcDir, "public")
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
addServerHandler({
|
|
134
|
+
route: "/__nuxt_studio/dev/content/**",
|
|
135
|
+
handler: runtime("./server/routes/dev/content/[...path]")
|
|
136
|
+
});
|
|
137
|
+
addServerHandler({
|
|
138
|
+
route: "/__nuxt_studio/dev/public/**",
|
|
139
|
+
handler: runtime("./server/routes/dev/public/[...path]")
|
|
140
|
+
});
|
|
141
|
+
addVitePlugin({
|
|
142
|
+
name: "nuxt-studio",
|
|
143
|
+
configureServer: (server) => {
|
|
144
|
+
assetsStorage.watch((type, file) => {
|
|
145
|
+
server.ws.send({
|
|
146
|
+
type: "custom",
|
|
147
|
+
event: "nuxt-studio:media:update",
|
|
148
|
+
data: { type, id: `public-assets/${file}` }
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
},
|
|
152
|
+
closeWatcher: () => {
|
|
153
|
+
assetsStorage.unwatch();
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
const assetsStorage = createStorage({
|
|
158
|
+
driver: fsDriver({
|
|
159
|
+
base: resolve(nuxt.options.rootDir, "public")
|
|
160
|
+
})
|
|
161
|
+
});
|
|
162
|
+
addTemplate({
|
|
163
|
+
filename: "studio-public-assets.mjs",
|
|
164
|
+
getContents: () => options.development.sync ? getAssetsStorageDevTemplate() : getAssetsStorageTemplate(assetsStorage)
|
|
165
|
+
});
|
|
166
|
+
addServerHandler({
|
|
167
|
+
route: "/__nuxt_studio/auth/github",
|
|
168
|
+
handler: runtime("./server/routes/auth/github.get")
|
|
169
|
+
});
|
|
170
|
+
addServerHandler({
|
|
171
|
+
route: "/__nuxt_studio/auth/session",
|
|
172
|
+
handler: runtime("./server/routes/auth/session.get")
|
|
173
|
+
});
|
|
174
|
+
addServerHandler({
|
|
175
|
+
method: "delete",
|
|
176
|
+
route: "/__nuxt_studio/auth/session",
|
|
177
|
+
handler: runtime("./server/routes/auth/session.delete")
|
|
178
|
+
});
|
|
179
|
+
addServerHandler({ route: options.route, handler: runtime("./server/routes/admin") });
|
|
180
|
+
addServerHandler({ route: "/__nuxt_studio/meta", handler: runtime("./server/routes/meta") });
|
|
181
|
+
addServerHandler({ route: "/sw.js", handler: runtime("./server/routes/sw") });
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
export { module as default };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ComponentMeta } from 'nuxt-studio/app';
|
|
2
|
+
export declare const useHostMeta: () => {
|
|
3
|
+
meta: import("vue").Ref<ComponentMeta | undefined, ComponentMeta | undefined>;
|
|
4
|
+
fetch: () => Promise<void>;
|
|
5
|
+
componentsMeta: import("vue").ShallowRef<ComponentMeta[], ComponentMeta[]>;
|
|
6
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { createSharedComposable } from "@vueuse/core";
|
|
2
|
+
import { ref, shallowRef } from "vue";
|
|
3
|
+
export const useHostMeta = createSharedComposable(() => {
|
|
4
|
+
const componentsMeta = shallowRef([]);
|
|
5
|
+
const meta = ref();
|
|
6
|
+
async function fetch() {
|
|
7
|
+
const data = await $fetch("/__nuxt_studio/meta", {
|
|
8
|
+
headers: { "content-type": "application/json" }
|
|
9
|
+
}).catch(() => ({ components: [] }));
|
|
10
|
+
componentsMeta.value = data.components || [];
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
meta,
|
|
14
|
+
fetch,
|
|
15
|
+
componentsMeta
|
|
16
|
+
};
|
|
17
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { useStudioHost as useStudioHostBase } from "./host.js";
|
|
2
|
+
import { generateContentFromDocument } from "nuxt-studio/app/utils";
|
|
3
|
+
import { createCollectionDocument, getCollectionInfo } from "./utils/collection.js";
|
|
4
|
+
import { createStorage } from "unstorage";
|
|
5
|
+
import httpDriver from "unstorage/drivers/http";
|
|
6
|
+
import { useRuntimeConfig } from "#imports";
|
|
7
|
+
import { collections } from "#content/preview";
|
|
8
|
+
import { debounce } from "perfect-debounce";
|
|
9
|
+
export function useStudioHost(user, repository) {
|
|
10
|
+
const host = useStudioHostBase(user, repository);
|
|
11
|
+
if (!useRuntimeConfig().public.studio.development.sync) {
|
|
12
|
+
return host;
|
|
13
|
+
}
|
|
14
|
+
host.meta.dev = true;
|
|
15
|
+
const devStorage = createStorage({
|
|
16
|
+
driver: httpDriver({ base: "/__nuxt_studio/dev/content" })
|
|
17
|
+
});
|
|
18
|
+
host.app.requestRerender = () => {
|
|
19
|
+
};
|
|
20
|
+
host.document.upsert = debounce(async (id, upsertedDocument) => {
|
|
21
|
+
id = id.replace(/:/g, "/");
|
|
22
|
+
const collection = getCollectionInfo(id, collections).collection;
|
|
23
|
+
const doc = createCollectionDocument(collection, id, upsertedDocument);
|
|
24
|
+
const content = await generateContentFromDocument(doc);
|
|
25
|
+
await devStorage.setItem(host.document.getFileSystemPath(id), content, {
|
|
26
|
+
headers: {
|
|
27
|
+
"content-type": "text/plain"
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}, 100);
|
|
31
|
+
host.document.delete = async (id) => {
|
|
32
|
+
await devStorage.removeItem(host.document.getFileSystemPath(id.replace(/:/g, "/")));
|
|
33
|
+
};
|
|
34
|
+
host.on.documentUpdate = (fn) => {
|
|
35
|
+
import.meta.hot.on("nuxt-content:update", (data) => {
|
|
36
|
+
const isRemoved = data.queries.length === 0;
|
|
37
|
+
fn(data.key, isRemoved ? "remove" : "update");
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
host.on.mediaUpdate = (fn) => {
|
|
41
|
+
import.meta.hot.on("nuxt-studio:media:update", (data) => {
|
|
42
|
+
fn(data.id, data.type);
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
return host;
|
|
46
|
+
}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { ref } from "vue";
|
|
2
|
+
import { ensure } from "./utils/ensure.js";
|
|
3
|
+
import { getCollectionByFilePath, generateIdFromFsPath, createCollectionDocument, generateRecordDeletion, generateRecordInsert, getCollectionInfo, normalizeDocument } from "./utils/collection.js";
|
|
4
|
+
import { kebabCase } from "scule";
|
|
5
|
+
import { generateDocumentFromContent } from "nuxt-studio/app/utils";
|
|
6
|
+
import { clearError, getAppManifest, queryCollection, queryCollectionItemSurroundings, queryCollectionNavigation, queryCollectionSearchSections } from "#imports";
|
|
7
|
+
import { collections } from "#content/preview";
|
|
8
|
+
import { publicAssetsStorage } from "#build/studio-public-assets";
|
|
9
|
+
import { useHostMeta } from "./composables/useMeta.js";
|
|
10
|
+
function getSidebarWidth() {
|
|
11
|
+
let sidebarWidth = 440;
|
|
12
|
+
if (typeof window !== "undefined" && window.localStorage) {
|
|
13
|
+
const savedWidth = localStorage.getItem("studio-sidebar-width");
|
|
14
|
+
if (savedWidth) {
|
|
15
|
+
const width = Number.parseInt(savedWidth, 10);
|
|
16
|
+
if (!Number.isNaN(width)) {
|
|
17
|
+
sidebarWidth = width;
|
|
18
|
+
return width;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return sidebarWidth;
|
|
23
|
+
}
|
|
24
|
+
function getHostStyles() {
|
|
25
|
+
const currentWidth = getSidebarWidth();
|
|
26
|
+
return {
|
|
27
|
+
"body[data-studio-active]": {
|
|
28
|
+
transition: "margin 0.2s ease"
|
|
29
|
+
},
|
|
30
|
+
"body[data-studio-active][data-expand-sidebar]": {
|
|
31
|
+
marginLeft: `${currentWidth}px`
|
|
32
|
+
}
|
|
33
|
+
// 'body[data-studio-active][data-expand-toolbar]': {
|
|
34
|
+
// marginTop: '60px',
|
|
35
|
+
// },
|
|
36
|
+
// 'body[data-studio-active][data-expand-sidebar][data-expand-toolbar]': {
|
|
37
|
+
// marginLeft: `${currentWidth}px`,
|
|
38
|
+
// marginTop: '60px',
|
|
39
|
+
// },
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function getLocalColorMode() {
|
|
43
|
+
return document.documentElement.classList.contains("dark") ? "dark" : "light";
|
|
44
|
+
}
|
|
45
|
+
export function useStudioHost(user, repository) {
|
|
46
|
+
let localDatabaseAdapter = null;
|
|
47
|
+
let colorMode = getLocalColorMode();
|
|
48
|
+
const isMounted = ref(false);
|
|
49
|
+
const meta = useHostMeta();
|
|
50
|
+
function useNuxtApp() {
|
|
51
|
+
return window.useNuxtApp();
|
|
52
|
+
}
|
|
53
|
+
function useRouter() {
|
|
54
|
+
return useNuxtApp().$router;
|
|
55
|
+
}
|
|
56
|
+
function useContent() {
|
|
57
|
+
const $content = useNuxtApp().$content || {};
|
|
58
|
+
return {
|
|
59
|
+
...$content,
|
|
60
|
+
queryCollection,
|
|
61
|
+
queryCollectionItemSurroundings,
|
|
62
|
+
queryCollectionNavigation,
|
|
63
|
+
queryCollectionSearchSections,
|
|
64
|
+
collections
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function useContentDatabaseAdapter(collection) {
|
|
68
|
+
return localDatabaseAdapter(collection);
|
|
69
|
+
}
|
|
70
|
+
function useContentCollections() {
|
|
71
|
+
return Object.fromEntries(
|
|
72
|
+
Object.entries(useContent().collections).filter(([, collection]) => {
|
|
73
|
+
if (!collection.source.length || collection.source.some((source) => source.repository || source._custom)) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
return true;
|
|
77
|
+
})
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
function useContentCollectionQuery(collection) {
|
|
81
|
+
return useContent().queryCollection(collection);
|
|
82
|
+
}
|
|
83
|
+
const host = {
|
|
84
|
+
meta: {
|
|
85
|
+
dev: false,
|
|
86
|
+
components: () => meta.componentsMeta.value
|
|
87
|
+
},
|
|
88
|
+
on: {
|
|
89
|
+
routeChange: (fn) => {
|
|
90
|
+
const router = useRouter();
|
|
91
|
+
router?.afterEach?.((to, from) => {
|
|
92
|
+
fn(to, from);
|
|
93
|
+
});
|
|
94
|
+
},
|
|
95
|
+
mounted: (fn) => ensure(() => isMounted.value, 400).then(fn),
|
|
96
|
+
beforeUnload: (fn) => {
|
|
97
|
+
host.ui.deactivateStudio();
|
|
98
|
+
ensure(() => isMounted.value).then(() => {
|
|
99
|
+
window.addEventListener("beforeunload", fn);
|
|
100
|
+
});
|
|
101
|
+
},
|
|
102
|
+
colorModeChange: (fn) => {
|
|
103
|
+
const localColorModeObserver = new MutationObserver(() => {
|
|
104
|
+
colorMode = getLocalColorMode();
|
|
105
|
+
fn(colorMode);
|
|
106
|
+
});
|
|
107
|
+
localColorModeObserver.observe(document.documentElement, {
|
|
108
|
+
attributes: true,
|
|
109
|
+
attributeFilter: ["class"]
|
|
110
|
+
});
|
|
111
|
+
},
|
|
112
|
+
manifestUpdate: (fn) => {
|
|
113
|
+
useNuxtApp().hooks.hookOnce("app:manifest:update", (meta2) => fn(meta2.id));
|
|
114
|
+
},
|
|
115
|
+
documentUpdate: (_fn) => {
|
|
116
|
+
},
|
|
117
|
+
mediaUpdate: (_fn) => {
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
ui: {
|
|
121
|
+
colorMode,
|
|
122
|
+
activateStudio: () => {
|
|
123
|
+
document.body.setAttribute("data-studio-active", "true");
|
|
124
|
+
},
|
|
125
|
+
deactivateStudio: () => {
|
|
126
|
+
document.body.removeAttribute("data-studio-active");
|
|
127
|
+
host.ui.collapseSidebar();
|
|
128
|
+
host.ui.updateStyles();
|
|
129
|
+
},
|
|
130
|
+
expandSidebar: () => {
|
|
131
|
+
document.body.setAttribute("data-expand-sidebar", "true");
|
|
132
|
+
host.ui.updateStyles();
|
|
133
|
+
},
|
|
134
|
+
collapseSidebar: () => {
|
|
135
|
+
document.body.removeAttribute("data-expand-sidebar");
|
|
136
|
+
host.ui.updateStyles();
|
|
137
|
+
},
|
|
138
|
+
updateStyles: () => {
|
|
139
|
+
const hostStyles = getHostStyles();
|
|
140
|
+
const styles = Object.keys(hostStyles).map((selector) => {
|
|
141
|
+
if (selector === "css") return hostStyles.css || "";
|
|
142
|
+
const styleText = Object.entries(hostStyles[selector]).map(([key, value]) => `${kebabCase(key)}: ${value}`).join(";");
|
|
143
|
+
return `${selector} { ${styleText} }`;
|
|
144
|
+
}).join("");
|
|
145
|
+
let styleElement = document.querySelector("[data-studio-style]");
|
|
146
|
+
if (!styleElement) {
|
|
147
|
+
styleElement = document.createElement("style");
|
|
148
|
+
styleElement.setAttribute("data-studio-style", "");
|
|
149
|
+
document.head.appendChild(styleElement);
|
|
150
|
+
}
|
|
151
|
+
styleElement.textContent = styles;
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
repository,
|
|
155
|
+
// New API
|
|
156
|
+
user: {
|
|
157
|
+
get: () => user
|
|
158
|
+
},
|
|
159
|
+
document: {
|
|
160
|
+
get: async (id) => {
|
|
161
|
+
const item = await useContentCollectionQuery(id.split("/")[0]).where("id", "=", id).first();
|
|
162
|
+
return normalizeDocument(item);
|
|
163
|
+
},
|
|
164
|
+
getFileSystemPath: (id) => {
|
|
165
|
+
return getCollectionInfo(id, useContentCollections()).fsPath;
|
|
166
|
+
},
|
|
167
|
+
list: async () => {
|
|
168
|
+
const collections2 = Object.keys(useContentCollections()).filter((c) => c !== "info");
|
|
169
|
+
const contents = await Promise.all(collections2.map(async (collection) => {
|
|
170
|
+
return await useContentCollectionQuery(collection).all();
|
|
171
|
+
}));
|
|
172
|
+
return contents.flat();
|
|
173
|
+
},
|
|
174
|
+
create: async (fsPath, content) => {
|
|
175
|
+
const collections2 = useContentCollections();
|
|
176
|
+
const collectionInfo = getCollectionByFilePath(fsPath, collections2);
|
|
177
|
+
const id = generateIdFromFsPath(fsPath, collectionInfo);
|
|
178
|
+
const existingDocument = await host.document.get(id);
|
|
179
|
+
if (existingDocument) {
|
|
180
|
+
throw new Error(`Cannot create document with id "${id}": document already exists.`);
|
|
181
|
+
}
|
|
182
|
+
const document2 = await generateDocumentFromContent(id, content);
|
|
183
|
+
const collectionDocument = createCollectionDocument(collectionInfo, id, document2);
|
|
184
|
+
await host.document.upsert(id, collectionDocument);
|
|
185
|
+
return collectionDocument;
|
|
186
|
+
},
|
|
187
|
+
upsert: async (id, document2) => {
|
|
188
|
+
id = id.replace(/:/g, "/");
|
|
189
|
+
const collection = getCollectionInfo(id, useContentCollections()).collection;
|
|
190
|
+
const doc = createCollectionDocument(collection, id, document2);
|
|
191
|
+
await useContentDatabaseAdapter(collection.name).exec(generateRecordDeletion(collection, id));
|
|
192
|
+
await useContentDatabaseAdapter(collection.name).exec(generateRecordInsert(collection, doc));
|
|
193
|
+
},
|
|
194
|
+
delete: async (id) => {
|
|
195
|
+
id = id.replace(/:/g, "/");
|
|
196
|
+
const collection = getCollectionInfo(id, useContentCollections()).collection;
|
|
197
|
+
await useContentDatabaseAdapter(collection.name).exec(generateRecordDeletion(collection, id));
|
|
198
|
+
},
|
|
199
|
+
detectActives: () => {
|
|
200
|
+
const wrappers = document.querySelectorAll("[data-content-id]");
|
|
201
|
+
return Array.from(wrappers).map((wrapper) => {
|
|
202
|
+
const id = wrapper.getAttribute("data-content-id");
|
|
203
|
+
const title = id.split(/[/:]/).pop() || id;
|
|
204
|
+
return {
|
|
205
|
+
id,
|
|
206
|
+
title
|
|
207
|
+
};
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
},
|
|
211
|
+
media: {
|
|
212
|
+
get: async (id) => {
|
|
213
|
+
return await publicAssetsStorage.getItem(id);
|
|
214
|
+
},
|
|
215
|
+
getFileSystemPath: (id) => {
|
|
216
|
+
return id.split("/").slice(1).join("/");
|
|
217
|
+
},
|
|
218
|
+
list: async () => {
|
|
219
|
+
return await Promise.all(await publicAssetsStorage.getKeys().then((keys) => keys.map((key) => publicAssetsStorage.getItem(key))));
|
|
220
|
+
},
|
|
221
|
+
upsert: async (id, media) => {
|
|
222
|
+
await publicAssetsStorage.setItem(id, media);
|
|
223
|
+
},
|
|
224
|
+
delete: async (id) => {
|
|
225
|
+
await publicAssetsStorage.removeItem(id);
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
app: {
|
|
229
|
+
getManifestId: async () => {
|
|
230
|
+
const manifest = await getAppManifest();
|
|
231
|
+
return manifest.id;
|
|
232
|
+
},
|
|
233
|
+
requestRerender: async () => {
|
|
234
|
+
if (useNuxtApp().payload.error) {
|
|
235
|
+
await clearError({ redirect: `?t=${Date.now()}` });
|
|
236
|
+
}
|
|
237
|
+
useNuxtApp().hooks.callHookParallel("app:data:refresh");
|
|
238
|
+
},
|
|
239
|
+
navigateTo: (path) => {
|
|
240
|
+
useRouter().push(path);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
(async () => {
|
|
245
|
+
host.ui.activateStudio();
|
|
246
|
+
ensure(() => useContent().queryCollection !== void 0, 500).then(() => ensure(() => useContent().loadLocalDatabase !== void 0)).then(() => useContent().loadLocalDatabase()).then((_localDatabaseAdapter) => {
|
|
247
|
+
localDatabaseAdapter = _localDatabaseAdapter;
|
|
248
|
+
isMounted.value = true;
|
|
249
|
+
}).then(() => {
|
|
250
|
+
if ("serviceWorker" in navigator) {
|
|
251
|
+
navigator.serviceWorker.register("/sw.js");
|
|
252
|
+
}
|
|
253
|
+
return meta.fetch();
|
|
254
|
+
});
|
|
255
|
+
})();
|
|
256
|
+
return host;
|
|
257
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { defineNuxtPlugin, useRuntimeConfig } from "#imports";
|
|
2
|
+
import { defineStudioActivationPlugin } from "../utils/activation.js";
|
|
3
|
+
export default defineNuxtPlugin(() => {
|
|
4
|
+
defineStudioActivationPlugin(async (user) => {
|
|
5
|
+
const config = useRuntimeConfig();
|
|
6
|
+
console.log(`
|
|
7
|
+
\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557
|
|
8
|
+
\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u2588\u2588\u2551 \u2588\u2588\u2551
|
|
9
|
+
\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551
|
|
10
|
+
\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u255A\u2588\u2588\u2557 \u2588\u2588\u2554\u255D
|
|
11
|
+
\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2588\u2554\u255D
|
|
12
|
+
\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u255D
|
|
13
|
+
`);
|
|
14
|
+
const host = await import("../host.dev.js").then((m) => m.useStudioHost);
|
|
15
|
+
window.useStudioHost = () => host(user, config.public.studio.repository);
|
|
16
|
+
const el = document.createElement("script");
|
|
17
|
+
el.src = `${config.public.studio?.development?.server}/src/main.ts`;
|
|
18
|
+
el.type = "module";
|
|
19
|
+
document.body.appendChild(el);
|
|
20
|
+
const wp = document.createElement("nuxt-studio");
|
|
21
|
+
document.body.appendChild(wp);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { defineNuxtPlugin, useRuntimeConfig } from "#imports";
|
|
2
|
+
import { defineStudioActivationPlugin } from "../utils/activation.js";
|
|
3
|
+
export default defineNuxtPlugin(() => {
|
|
4
|
+
defineStudioActivationPlugin(async (user) => {
|
|
5
|
+
const config = useRuntimeConfig();
|
|
6
|
+
const host = await import("../host.js").then((m) => m.useStudioHost);
|
|
7
|
+
window.useStudioHost = () => host(user, config.public.studio.repository);
|
|
8
|
+
await import("nuxt-studio/app");
|
|
9
|
+
document.body.appendChild(document.createElement("nuxt-studio"));
|
|
10
|
+
});
|
|
11
|
+
});
|