rimecms 0.24.6 → 0.25.1

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.
Files changed (88) hide show
  1. package/dist/adapter-sqlite/generate-schema/index.server.js +9 -9
  2. package/dist/adapter-sqlite/generate-schema/root.server.d.ts +5 -0
  3. package/dist/adapter-sqlite/generate-schema/root.server.js +5 -0
  4. package/dist/adapter-sqlite/generate-schema/templates.server.js +9 -6
  5. package/dist/core/collections/upload/upload.d.ts +2 -1
  6. package/dist/core/collections/upload/util/converter.js +4 -3
  7. package/dist/core/config/client/augment-directories.d.ts +6 -0
  8. package/dist/core/config/client/augment-directories.js +11 -0
  9. package/dist/core/config/client/build-config.d.ts +2 -0
  10. package/dist/core/config/client/build-config.js +3 -1
  11. package/dist/core/config/server/augment-directories.server.d.ts +6 -0
  12. package/dist/core/config/server/augment-directories.server.js +37 -0
  13. package/dist/core/config/server/build-config.server.d.ts +2 -0
  14. package/dist/core/config/server/build-config.server.js +4 -6
  15. package/dist/core/config/shared/upload-directories.d.ts +7 -2
  16. package/dist/core/config/shared/upload-directories.js +118 -48
  17. package/dist/core/config/types.d.ts +6 -0
  18. package/dist/core/naming.d.ts +1 -1
  19. package/dist/core/naming.js +1 -1
  20. package/dist/core/operations/hooks/before-read/set-document-title.server.js +1 -1
  21. package/dist/fields/blocks/component/Block.svelte +1 -1
  22. package/dist/fields/blocks/component/Block.svelte.d.ts +1 -1
  23. package/dist/fields/blocks/component/props.d.ts +1 -1
  24. package/dist/fields/combobox/component/props.d.ts +1 -1
  25. package/dist/fields/date/component/Date.svelte +8 -4
  26. package/dist/fields/date/component/Date.svelte.d.ts +1 -1
  27. package/dist/fields/email/component/props.d.ts +1 -1
  28. package/dist/fields/group/component/Group.svelte +1 -1
  29. package/dist/fields/link/component/RessourceInput.svelte +1 -1
  30. package/dist/fields/relation/component/Relation.svelte +3 -2
  31. package/dist/fields/relation/component/upload/Browse.svelte +1 -1
  32. package/dist/fields/relation/index.d.ts +3 -2
  33. package/dist/fields/rich-text/component/props.d.ts +1 -1
  34. package/dist/fields/rich-text/core/features/link/component/link-selector.svelte +23 -5
  35. package/dist/fields/rich-text/core/features/resource/resource.svelte +1 -1
  36. package/dist/fields/rich-text/core/features/upload/upload.svelte +10 -3
  37. package/dist/fields/rich-text/core/render-rich-text.svelte +1 -1
  38. package/dist/fields/rich-text/core/render-rich-text.svelte.d.ts +1 -1
  39. package/dist/fields/select/component/props.d.ts +1 -1
  40. package/dist/fields/text/component/props.d.ts +1 -1
  41. package/dist/fields/textarea/component/props.d.ts +2 -2
  42. package/dist/fields/time/component/props.d.ts +1 -1
  43. package/dist/panel/components/fields/RenderFields.svelte +7 -4
  44. package/dist/panel/components/fields/RenderFields.svelte.d.ts +4 -2
  45. package/dist/panel/components/sections/collection/grid/CollectionGrid.svelte +6 -14
  46. package/dist/panel/components/sections/collection/grid/grid-item/FolderEdit.svelte +79 -0
  47. package/dist/panel/components/sections/collection/grid/grid-item/FolderEdit.svelte.d.ts +10 -0
  48. package/dist/panel/components/sections/collection/grid/grid-item/FolderWithActions.svelte +11 -44
  49. package/dist/panel/components/sections/collection/grid/grid-item/FolderWithActions.svelte.d.ts +0 -2
  50. package/dist/panel/components/sections/collection/header/Header.svelte +1 -1
  51. package/dist/panel/components/sections/collection/header/create-folder/CreateFolder.svelte +90 -0
  52. package/dist/panel/components/sections/collection/header/create-folder/CreateFolder.svelte.d.ts +7 -0
  53. package/dist/panel/components/sections/collection/tree/CollectionTree.svelte +1 -1
  54. package/dist/panel/components/sections/document/AuthFooter.svelte +13 -4
  55. package/dist/panel/components/sections/document/AuthFooter.svelte.d.ts +1 -1
  56. package/dist/panel/components/sections/document/ButtonStatus.svelte +1 -1
  57. package/dist/panel/components/sections/document/ButtonStatus.svelte.d.ts +1 -1
  58. package/dist/panel/components/sections/document/Document.svelte +4 -4
  59. package/dist/panel/components/sections/document/FloatingUI.svelte +4 -2
  60. package/dist/panel/components/sections/document/FloatingUI.svelte.d.ts +1 -1
  61. package/dist/panel/components/sections/document/Header.svelte +1 -1
  62. package/dist/panel/components/sections/document/Header.svelte.d.ts +1 -1
  63. package/dist/panel/components/sections/document/Settings.svelte +7 -3
  64. package/dist/panel/components/sections/document/Settings.svelte.d.ts +1 -1
  65. package/dist/panel/components/sections/document/upload-header/UploadHeader.svelte +1 -1
  66. package/dist/panel/components/sections/document/upload-header/UploadHeader.svelte.d.ts +1 -1
  67. package/dist/panel/components/ui/dialog/dialog-content.svelte +20 -5
  68. package/dist/panel/components/ui/dialog/dialog-content.svelte.d.ts +7 -2
  69. package/dist/panel/components/ui/language-switcher/LanguageSwitcher.svelte +39 -34
  70. package/dist/panel/components/ui/nav/Nav.svelte +7 -2
  71. package/dist/panel/components/ui/nav/NavItem.svelte +3 -2
  72. package/dist/panel/components/ui/nav/UserButton.svelte +4 -4
  73. package/dist/panel/context/collection.svelte.js +3 -1
  74. package/dist/panel/context/documentForm.svelte.d.ts +14 -6
  75. package/dist/panel/context/documentForm.svelte.js +15 -7
  76. package/dist/panel/context/locale.svelte.js +1 -1
  77. package/dist/panel/pages/auth/forgot-password/ForgotPassword.svelte +1 -0
  78. package/dist/panel/pages/collection/Collection.svelte +1 -1
  79. package/dist/panel/pages/collection-document/CollectionDocument.svelte +2 -2
  80. package/dist/panel/pages/dashboard/Dashboard.svelte +8 -8
  81. package/dist/panel/pages/dashboard/Dashboard.svelte.d.ts +1 -1
  82. package/dist/util/string.d.ts +14 -0
  83. package/dist/util/string.js +19 -0
  84. package/package.json +1 -1
  85. package/dist/core/collections/upload/directory-input-config.d.ts +0 -2
  86. package/dist/core/collections/upload/directory-input-config.js +0 -12
  87. package/dist/panel/components/sections/collection/header/CreateUploadFolder.svelte +0 -68
  88. package/dist/panel/components/sections/collection/header/CreateUploadFolder.svelte.d.ts +0 -7
@@ -1,11 +1,11 @@
1
- import { withDirectoriesSuffix, withVersionsSuffix } from '../../core/naming.js';
1
+ import { withVersionsSuffix } from '../../core/naming.js';
2
2
  import { date } from '../../fields/date/index.js';
3
3
  import { getFieldPrivateModule } from '../../fields/index.server.js';
4
- import { toCamelCase, toPascalCase, toSnakeCase } from '../../util/string.js';
4
+ import { toCamelCase, toCamelCasePreserveTrailingUnderscoreSuffix, toPascalCase, toSnakeCase } from '../../util/string.js';
5
5
  import { generateRelationshipDefinitions } from './relations/definition.server.js';
6
6
  import { generateJunctionTableDefinition } from './relations/junction.server.js';
7
7
  import buildRootTable from './root.server.js';
8
- import { templateAPIKey, templateAuth, templateDirectories, templateExportRelationsFieldsToTable, templateExportSchema, templateExportTables, templateHead, templateImports, templateRelationMany, templateRelationOne, templateTable } from './templates.server.js';
8
+ import { templateAPIKey, templateAuth, templateExportRelationsFieldsToTable, templateExportSchema, templateExportTables, templateHead, templateImports, templateRelationMany, templateRelationOne, templateTable } from './templates.server.js';
9
9
  import write from './write.server.js';
10
10
  export async function generateSchemaString(config) {
11
11
  const collections = (config.collections || []).filter((c) => c._generateSchema !== false);
@@ -16,7 +16,7 @@ export async function generateSchemaString(config) {
16
16
  let relationFieldsExportDic = {};
17
17
  const blocksRegister = [];
18
18
  for (const collection of collections) {
19
- const collectionSlug = toCamelCase(collection.slug);
19
+ const collectionSlug = toCamelCasePreserveTrailingUnderscoreSuffix(collection.slug);
20
20
  let rootTableName = collectionSlug;
21
21
  let versionsRelationsDefinitions = [];
22
22
  schema.push(templateHead(collectionSlug));
@@ -32,7 +32,7 @@ export async function generateSchemaString(config) {
32
32
  // Split fields that should be used on the root table
33
33
  const rootFieldsFromConfig = [...collection.fields].filter(isRootField);
34
34
  const rootFields = [...rootFieldsFromConfig, ...baseRootFields];
35
- // Buiuld the main root buildRootTable with only _root fields and created/updatedAt
35
+ // Build the main root buildRootTable with only _root fields and created/updatedAt
36
36
  const { schema: rootCollectionSchema } = await buildRootTable({
37
37
  blocksRegister: [],
38
38
  fields: rootFields,
@@ -98,10 +98,10 @@ export async function generateSchemaString(config) {
98
98
  ...relationFieldsExportDic,
99
99
  [rootTableName]: relationFieldsMap
100
100
  };
101
- if (collection.upload) {
102
- schema.push(templateDirectories(collection.slug));
103
- enumTables = [...enumTables, withDirectoriesSuffix(collection.slug)];
104
- }
101
+ // if (collection.upload) {
102
+ // schema.push(templateDirectories(collection.slug));
103
+ // enumTables = [...enumTables, withDirectoriesSuffix(collection.slug)];
104
+ // }
105
105
  schema.push(collectionSchema, junctionTable, ...versionsRelationsDefinitions, relationsDefinitions);
106
106
  }
107
107
  /**
@@ -20,5 +20,10 @@ type Return = {
20
20
  relationsDic: Record<string, string[]>;
21
21
  relationFieldsHasLocale: boolean;
22
22
  };
23
+ /**
24
+ * This function generates the root table schema for collection/areas, including its localized version if needed,
25
+ * and also generates tables for blocks and tree fields.
26
+ * It also keeps track of relation fields and their localization status to properly generate relations later on.
27
+ */
23
28
  declare const buildRootTable: ({ fields: incomingFields, tableName, rootName, hasParent, locales, relationFieldsMap, relationsDic, hasAuth, versionsFrom, blocksRegister }: Args) => Promise<Return>;
24
29
  export default buildRootTable;
@@ -11,6 +11,11 @@ import { TreeBuilder } from '../../fields/tree/index.js';
11
11
  import { toPascalCase } from '../../util/string.js';
12
12
  import { templateHasAuth, templateLocale, templateParent, templateTable } from './templates.server.js';
13
13
  const p = toPascalCase;
14
+ /**
15
+ * This function generates the root table schema for collection/areas, including its localized version if needed,
16
+ * and also generates tables for blocks and tree fields.
17
+ * It also keeps track of relation fields and their localization status to properly generate relations later on.
18
+ */
14
19
  const buildRootTable = async ({ fields: incomingFields, tableName, rootName, hasParent, locales, relationFieldsMap = {}, relationsDic = {}, hasAuth, versionsFrom, blocksRegister }) => {
15
20
  const blocksTables = [];
16
21
  let relationFieldsHasLocale = false;
@@ -25,12 +25,15 @@ const pk = () => text("id").primaryKey().$defaultFn(() => crypto.randomUUID());
25
25
  * })
26
26
  * ```
27
27
  */
28
- export const templateTable = (table, content) => `
29
- export const ${table} = sqliteTable( '${s(table)}', {
30
- id: pk(),
31
- ${content}
32
- })
33
- `;
28
+ export const templateTable = (table, content) => {
29
+ if (!content.includes('id:')) {
30
+ content = `id: pk(),\n${content}`;
31
+ }
32
+ return `export const ${table} = sqliteTable( '${s(table)}', {
33
+ ${content}
34
+ })
35
+ `;
36
+ };
34
37
  /**
35
38
  * Generates a locale field for internationalized tables
36
39
  *
@@ -1,3 +1,4 @@
1
+ import type { GenericDoc } from '../../../types.js';
1
2
  import type { UploadPath } from './util/path.js';
2
3
 
3
4
  export type JsonFile = {
@@ -8,7 +9,7 @@ export type JsonFile = {
8
9
  lastModified?: number;
9
10
  };
10
11
 
11
- export type Directory = {
12
+ export type Directory = GenericDoc & {
12
13
  id: UploadPath;
13
14
  name: string;
14
15
  parent: UploadPath | null;
@@ -49,7 +49,8 @@ export const jsonFileToFile = (jsonFile) => {
49
49
  })
50
50
  };
51
51
  }
52
- catch {
52
+ catch (err) {
53
+ logger.error('Error converting base64 to File:', err.message);
53
54
  throw new RimeError(RimeError.UPLOAD, 'Invalid base64 content');
54
55
  }
55
56
  };
@@ -65,7 +66,7 @@ export async function filePathToBase64(filePath) {
65
66
  return `data:${mimeType};base64,${base64}`;
66
67
  }
67
68
  catch (error) {
68
- console.error('Error:', error);
69
+ logger.error('Error converting file path to base64:', error.message);
69
70
  throw error;
70
71
  }
71
72
  }
@@ -90,7 +91,7 @@ export async function filePathToFile(filePath) {
90
91
  const ext = path.extname(filePath).slice(1).toLowerCase();
91
92
  const mimeType = getMimeTypeFromExtension(ext) || 'application/octet-stream';
92
93
  // Create a Blob with the file content
93
- const blob = new Blob([buffer], { type: mimeType });
94
+ const blob = new Blob([new Uint8Array(buffer)], { type: mimeType });
94
95
  // Create and return a File object
95
96
  return new File([blob], filename, {
96
97
  type: mimeType,
@@ -0,0 +1,6 @@
1
+ import type { BuiltCollection } from '../types.js';
2
+ export declare const augmentDirectories: <T extends {
3
+ collections?: BuiltCollection[];
4
+ }>(config: T) => T & {
5
+ readonly collections: readonly BuiltCollection[];
6
+ };
@@ -0,0 +1,11 @@
1
+ import { isUploadConfig } from '../../collections/upload/util/config.js';
2
+ import { makeUploadDirectoriesCollectionClient } from '../shared/upload-directories';
3
+ export const augmentDirectories = (config) => {
4
+ const direcotriesCollections = config.collections
5
+ ?.filter(isUploadConfig)
6
+ .map(makeUploadDirectoriesCollectionClient);
7
+ return {
8
+ ...config,
9
+ collections: [...(config.collections || []), ...(direcotriesCollections || [])]
10
+ };
11
+ };
@@ -34,6 +34,8 @@ export declare const buildConfigClient: <C extends SanitizedConfigClient>(config
34
34
  };
35
35
  readonly css?: string;
36
36
  };
37
+ } & {
38
+ readonly collections: readonly import("../types.js").BuiltCollection[];
37
39
  } & {
38
40
  readonly plugins: (import("../../plugins/index.js").PluginClient | {
39
41
  readonly name: "cache/client";
@@ -1,4 +1,5 @@
1
1
  import { augmentIcons } from '../shared/augment-icons.js';
2
+ import { augmentDirectories } from './augment-directories.js';
2
3
  import { augmentPanel } from './augment-panel.js';
3
4
  import { augmentPlugins } from './augment-plugins.js';
4
5
  import { augmentStaff } from './augment-staff.js';
@@ -6,6 +7,7 @@ export const buildConfigClient = (config) => {
6
7
  const withStaff = augmentStaff(config);
7
8
  const withIcons = augmentIcons(withStaff);
8
9
  const withPanel = augmentPanel(withIcons);
9
- const output = augmentPlugins(withPanel);
10
+ const withDirectories = augmentDirectories(withPanel);
11
+ const output = augmentPlugins(withDirectories);
10
12
  return output;
11
13
  };
@@ -0,0 +1,6 @@
1
+ import type { BuiltCollection } from '../types.js';
2
+ export declare const augmentDirectoriesServer: <T extends {
3
+ collections?: BuiltCollection[];
4
+ }>(config: T) => T & {
5
+ readonly collections: readonly BuiltCollection[];
6
+ };
@@ -0,0 +1,37 @@
1
+ import { augmentHooks } from '../../collections/config/augment-hooks.server';
2
+ import { exctractPath } from '../../collections/upload/hooks/extract-path.server';
3
+ import { prepareDirectoryChildren, updateDirectoryChildren } from '../../collections/upload/hooks/update-directory-children.server';
4
+ import { isUploadConfig } from '../../collections/upload/util/config.js';
5
+ import { makeUploadDirectoriesCollectionClient } from '../shared/upload-directories';
6
+ export const augmentDirectoriesServer = (config) => {
7
+ const direcotriesCollections = config.collections
8
+ ?.filter(isUploadConfig)
9
+ .map(makeUploadDirectoriesCollectionServer);
10
+ return {
11
+ ...config,
12
+ collections: [...(config.collections || []), ...(direcotriesCollections || [])]
13
+ };
14
+ };
15
+ const makeUploadDirectoriesCollectionServer = (collection) => {
16
+ const collectionClient = makeUploadDirectoriesCollectionClient(collection);
17
+ const directoriesConfig = collection.upload.directories;
18
+ let directoriesCollection = {
19
+ ...collectionClient,
20
+ $hooks: {
21
+ beforeOperation: directoriesConfig?.$hooks?.beforeOperation || [],
22
+ beforeCreate: [exctractPath, ...(directoriesConfig?.$hooks?.beforeCreate || [])],
23
+ beforeRead: directoriesConfig?.$hooks?.beforeRead || [],
24
+ beforeUpdate: [
25
+ exctractPath,
26
+ prepareDirectoryChildren,
27
+ ...(directoriesConfig?.$hooks?.beforeUpdate || [])
28
+ ],
29
+ beforeDelete: directoriesConfig?.$hooks?.beforeDelete || [],
30
+ afterCreate: directoriesConfig?.$hooks?.afterCreate || [],
31
+ afterUpdate: [updateDirectoryChildren, ...(directoriesConfig?.$hooks?.afterUpdate || [])],
32
+ afterDelete: directoriesConfig?.$hooks?.afterDelete || []
33
+ }
34
+ };
35
+ directoriesCollection = augmentHooks(directoriesCollection);
36
+ return directoriesCollection;
37
+ };
@@ -4057,6 +4057,8 @@ declare function augmentConfig<T extends Config>(config: T): T & {
4057
4057
  }) => Promise<import("nodemailer/lib/smtp-transport/index.js").SentMessageInfo>;
4058
4058
  };
4059
4059
  })[]];
4060
+ } & {
4061
+ readonly collections: readonly import("../types.js").BuiltCollection[];
4060
4062
  } & {
4061
4063
  readonly plugins: (import("../../plugins/index.js").PluginClient | {
4062
4064
  readonly name: "cache/client";
@@ -3,9 +3,9 @@ import { augmentPanel } from '../client/augment-panel.js';
3
3
  import { augmentPlugins } from '../client/augment-plugins.js';
4
4
  import { augmentIcons } from '../shared/augment-icons.js';
5
5
  import { augmentPrototypes } from '../shared/augment-prototypes.js';
6
- import { makeUploadDirectoriesCollections } from '../shared/upload-directories.js';
7
6
  import { makeVersionsCollectionsAliases } from '../shared/versions-alias.server.js';
8
7
  import { augmentCORS } from './augment-cors.js';
8
+ import { augmentDirectoriesServer } from './augment-directories.server.js';
9
9
  import { augmentPanelAccess } from './augment-panel-access.server.js';
10
10
  import { augmentPluginsServer } from './augment-plugins.server.js';
11
11
  import { augmentStaffServer } from './augment-staff.server.js';
@@ -13,10 +13,7 @@ export const buildConfig = (config) => {
13
13
  const augmented = augmentConfig(config);
14
14
  // Versions collection aliases
15
15
  // create {slug}_versions collections
16
- const withVersions = makeVersionsCollectionsAliases(augmented);
17
- // Upload collection directories
18
- // create {slug}_directories collections
19
- const output = makeUploadDirectoriesCollections(withVersions);
16
+ const output = makeVersionsCollectionsAliases(augmented);
20
17
  return createRime(output);
21
18
  };
22
19
  function augmentConfig(config) {
@@ -27,6 +24,7 @@ function augmentConfig(config) {
27
24
  const withPanelAccess = augmentPanelAccess(withPanel);
28
25
  const withCORS = augmentCORS(withPanelAccess);
29
26
  const withPluginsServer = augmentPluginsServer(withCORS);
30
- const output = augmentPlugins(withPluginsServer);
27
+ const withDirectories = augmentDirectoriesServer(withPluginsServer);
28
+ const output = augmentPlugins(withDirectories);
31
29
  return output;
32
30
  }
@@ -1,6 +1,11 @@
1
- import type { Config } from '../types.js';
1
+ import type { WithUpload } from '../../collections/upload/util/config.js';
2
+ import type { BuiltCollection } from '../types.js';
2
3
  /**
3
4
  * Creates an upload directories collection for collections with upload enabled
4
5
  * Eg. for medias this will create a collection medias_directories
5
6
  */
6
- export declare function makeUploadDirectoriesCollections<C extends Config>(config: C): C;
7
+ /**
8
+ * Creates an upload directories collection for collections with upload enabled
9
+ * Eg. for medias this will create a collection medias_directories
10
+ */
11
+ export declare function makeUploadDirectoriesCollectionClient<C extends WithUpload<BuiltCollection>>(collection: C): BuiltCollection;
@@ -1,57 +1,127 @@
1
- import { augmentHooks } from '../../collections/config/augment-hooks.server.js';
2
- import { exctractPath } from '../../collections/upload/hooks/extract-path.server.js';
3
- import { prepareDirectoryChildren, updateDirectoryChildren } from '../../collections/upload/hooks/update-directory-children.server.js';
4
1
  import { validatePath } from '../../collections/upload/util/path.js';
5
2
  import { withDirectoriesSuffix } from '../../naming.js';
6
3
  import { date } from '../../../fields/date/index.js';
7
4
  import { text } from '../../../fields/text/index.js';
8
- import { toKebabCase } from '../../../util/string.js';
9
5
  /**
10
6
  * Creates an upload directories collection for collections with upload enabled
11
7
  * Eg. for medias this will create a collection medias_directories
12
8
  */
13
- export function makeUploadDirectoriesCollections(config) {
14
- for (const collection of config.collections || []) {
15
- if (collection.upload) {
16
- const slug = withDirectoriesSuffix(collection.slug);
17
- // If already created skip to the next colleciton
18
- // for exemple a versions collections of an upload
19
- // collection should not have a directories related table
20
- if ((config.collections || []).filter((c) => c.slug === slug).length)
21
- continue;
22
- // else create the directory collection
23
- let directoriesCollection = {
24
- slug: slug,
25
- kebab: withDirectoriesSuffix(toKebabCase(collection.slug)),
26
- versions: undefined,
27
- access: collection.access,
28
- fields: [
29
- text('id').validate(validatePath).unique().required(),
30
- text('name'),
31
- text('parent'),
32
- date('createdAt'),
33
- date('updatedAt')
34
- ],
35
- type: 'collection',
36
- label: {
37
- singular: `${collection.slug} directory`,
38
- plural: `${collection.slug} directories`
39
- },
40
- icon: collection.icon,
41
- $hooks: {
42
- beforeUpdate: [exctractPath, prepareDirectoryChildren],
43
- afterUpdate: [updateDirectoryChildren],
44
- beforeCreate: [exctractPath]
45
- },
46
- asTitle: 'path',
47
- asThumbnail: collection.asThumbnail,
48
- panel: false,
49
- _generateTypes: false,
50
- _generateSchema: false
51
- };
52
- directoriesCollection = augmentHooks(directoriesCollection);
53
- config.collections = [...(config.collections || []), directoriesCollection];
54
- }
55
- }
56
- return config;
9
+ // export function makeUploadDirectoriesCollections<C extends Config>(config: C) {
10
+ // for (const collection of config.collections || []) {
11
+ // if (collection.upload) {
12
+ // const slug = withDirectoriesSuffix(collection.slug);
13
+ // // If already created skip to the next colleciton
14
+ // // for exemple a versions collections of an upload
15
+ // // collection should not have a directories related table
16
+ // if ((config.collections || []).filter((c) => c.slug === slug).length) continue;
17
+ // const directoriesConfig = collection.upload.directories;
18
+ // // else create the directory collection
19
+ // let directoriesCollection: BuiltCollection = {
20
+ // slug: slug as CollectionSlug,
21
+ // kebab: withDirectoriesSuffix(toKebabCase(collection.slug)),
22
+ // versions: undefined,
23
+ // access: {
24
+ // read: directoriesConfig?.access?.read || collection.access.read,
25
+ // create: directoriesConfig?.access?.create || collection.access.create,
26
+ // update: directoriesConfig?.access?.update || collection.access.update,
27
+ // delete: directoriesConfig?.access?.delete || collection.access.delete
28
+ // },
29
+ // fields: [
30
+ // text('id').validate(validatePath).unique().required().hidden(),
31
+ // text('name').validate((value) => {
32
+ // const pattern = /^[a-zA-Z0-9-_ ]+$/;
33
+ // if (typeof value !== 'string' || !pattern.test(value)) {
34
+ // return 'Incorrect folder name';
35
+ // }
36
+ // return true;
37
+ // }),
38
+ // text('parent').hidden(),
39
+ // ...(directoriesConfig?.fields || []),
40
+ // date('createdAt').hidden(),
41
+ // date('updatedAt').hidden()
42
+ // ],
43
+ // type: 'collection',
44
+ // label: {
45
+ // singular: `${collection.slug} directory`,
46
+ // plural: `${collection.slug} directories`
47
+ // },
48
+ // icon: collection.icon,
49
+ // $hooks: {
50
+ // beforeOperation: directoriesConfig?.$hooks?.beforeOperation || [],
51
+ // beforeCreate: [exctractPath, ...(directoriesConfig?.$hooks?.beforeCreate || [])],
52
+ // beforeRead: directoriesConfig?.$hooks?.beforeRead || [],
53
+ // beforeUpdate: [
54
+ // exctractPath,
55
+ // prepareDirectoryChildren,
56
+ // ...(directoriesConfig?.$hooks?.beforeUpdate || [])
57
+ // ],
58
+ // beforeDelete: directoriesConfig?.$hooks?.beforeDelete || [],
59
+ // afterCreate: directoriesConfig?.$hooks?.afterCreate || [],
60
+ // afterUpdate: [updateDirectoryChildren, ...(directoriesConfig?.$hooks?.afterUpdate || [])],
61
+ // afterDelete: directoriesConfig?.$hooks?.afterDelete || []
62
+ // },
63
+ // asTitle: 'path',
64
+ // asThumbnail: collection.asThumbnail,
65
+ // panel: false
66
+ // // _generateTypes: false,
67
+ // // _generateSchema: false
68
+ // };
69
+ // directoriesCollection = augmentHooks(directoriesCollection);
70
+ // config.collections = [...(config.collections || []), directoriesCollection];
71
+ // }
72
+ // }
73
+ // return config;
74
+ // }
75
+ /**
76
+ * Creates an upload directories collection for collections with upload enabled
77
+ * Eg. for medias this will create a collection medias_directories
78
+ */
79
+ export function makeUploadDirectoriesCollectionClient(collection) {
80
+ const slug = withDirectoriesSuffix(collection.slug);
81
+ const directoriesConfig = collection.upload.directories;
82
+ console.log(collection.upload);
83
+ console.log(directoriesConfig?.fields);
84
+ // else create the directory collection
85
+ let directoriesCollection = {
86
+ slug: slug,
87
+ kebab: withDirectoriesSuffix(collection.kebab),
88
+ versions: undefined,
89
+ access: {
90
+ read: directoriesConfig?.access?.read || collection.access.read,
91
+ create: directoriesConfig?.access?.create || collection.access.create,
92
+ update: directoriesConfig?.access?.update || collection.access.update,
93
+ delete: directoriesConfig?.access?.delete || collection.access.delete
94
+ },
95
+ fields: [
96
+ text('id').validate(validatePath).unique().required().hidden(),
97
+ text('name')
98
+ .validate((value) => {
99
+ const pattern = /^[a-zA-Z0-9-_ ]+$/;
100
+ if (typeof value !== 'string' || !pattern.test(value)) {
101
+ return 'Incorrect folder name';
102
+ }
103
+ return true;
104
+ })
105
+ .onChange((value, { useField }) => {
106
+ const id = useField('id');
107
+ const parent = useField('parent');
108
+ const newPath = `${parent.value}:${value}`;
109
+ id.value = newPath;
110
+ }),
111
+ text('parent').hidden(),
112
+ ...(directoriesConfig?.fields || []),
113
+ date('createdAt').hidden(),
114
+ date('updatedAt').hidden()
115
+ ],
116
+ type: 'collection',
117
+ label: {
118
+ singular: `${collection.slug} directory`,
119
+ plural: `${collection.slug} directories`
120
+ },
121
+ icon: collection.icon,
122
+ asTitle: 'path',
123
+ asThumbnail: collection.asThumbnail,
124
+ panel: false
125
+ };
126
+ return directoriesCollection;
57
127
  }
@@ -219,6 +219,12 @@ export type UploadConfig = {
219
219
  * ```
220
220
  */
221
221
  accept?: string[];
222
+ /** Directories */
223
+ directories?: {
224
+ fields: FieldBuilder<Field>[];
225
+ access?: Access;
226
+ $hooks?: CollectionHooks<any>;
227
+ };
222
228
  };
223
229
  export type CollectionAuthConfig = ({
224
230
  type: 'password';
@@ -5,7 +5,7 @@ import type { CollectionSlug } from '../types.js';
5
5
  * Prevent a version table name from being used, force the use of the main one.
6
6
  *
7
7
  * @example
8
- * // Returns botth 'pages_directories'
8
+ * // Returns both 'pages_directories'
9
9
  * withDirectoriesSuffix('pages');
10
10
  * withDirectoriesSuffix('pages_versions');
11
11
  */
@@ -4,7 +4,7 @@
4
4
  * Prevent a version table name from being used, force the use of the main one.
5
5
  *
6
6
  * @example
7
- * // Returns botth 'pages_directories'
7
+ * // Returns both 'pages_directories'
8
8
  * withDirectoriesSuffix('pages');
9
9
  * withDirectoriesSuffix('pages_versions');
10
10
  */
@@ -1,5 +1,5 @@
1
+ import { richTextJSONToText } from '../../../../fields/rich-text/index.js';
1
2
  import { getValueAtPath, isObjectLiteral } from '../../../../util/object.js';
2
- import { richTextJSONToText } from '../../../../fields/rich-text/client.js';
3
3
  import { Hooks } from '../index.server.js';
4
4
  export const setDocumentTitle = Hooks.beforeRead(async (args) => {
5
5
  const config = args.config;
@@ -2,7 +2,7 @@
2
2
  import type { GenericBlock } from '../../../core/types/doc.js';
3
3
  import type { BlocksFieldBlock } from '../../types';
4
4
  import RenderFields from '../../../panel/components/fields/RenderFields.svelte';
5
- import { type DocumentFormContext } from '../../../panel/context/documentForm.svelte';
5
+ import { type DocumentFormContext } from '../../../panel/context/documentForm.svelte.js';
6
6
  import { useOnce } from '../../../panel/util/once.svelte.js';
7
7
  import { capitalize } from '../../../util/string.js';
8
8
  import { GripVertical, ToyBrick } from '@lucide/svelte';
@@ -1,5 +1,5 @@
1
1
  import type { BlocksFieldBlock } from '../../types';
2
- import { type DocumentFormContext } from '../../../panel/context/documentForm.svelte';
2
+ import { type DocumentFormContext } from '../../../panel/context/documentForm.svelte.js';
3
3
  type Props = {
4
4
  config: BlocksFieldBlock;
5
5
  path: string;
@@ -1,4 +1,4 @@
1
- import type { DocumentFormContext } from '../../../panel/context/documentForm.svelte';
1
+ import type { DocumentFormContext } from '../../../panel/context/documentForm.svelte.js';
2
2
  import type { BlocksField } from '../index.js';
3
3
  export type BlocksProps = {
4
4
  path: string;
@@ -1,4 +1,4 @@
1
- import type { DocumentFormContext } from '../../../panel/context/documentForm.svelte';
1
+ import type { DocumentFormContext } from '../../../panel/context/documentForm.svelte.js';
2
2
  import type { ComboBoxField } from '../index.js';
3
3
  export type ComboBoxProps = {
4
4
  path: string;
@@ -4,7 +4,7 @@
4
4
  import { Button } from '../../../panel/components/ui/button/index.js';
5
5
  import { Calendar } from '../../../panel/components/ui/calendar/index.js';
6
6
  import * as Dialog from '../../../panel/components/ui/dialog/index.js';
7
- import { type DocumentFormContext } from '../../../panel/context/documentForm.svelte';
7
+ import { type DocumentFormContext } from '../../../panel/context/documentForm.svelte.js';
8
8
  import { getLocaleContext } from '../../../panel/context/locale.svelte';
9
9
  import { CalendarDate, getLocalTimeZone, type DateValue } from '@internationalized/date';
10
10
  import { Calendar as CalendarIcon } from '@lucide/svelte';
@@ -48,7 +48,7 @@
48
48
  </script>
49
49
 
50
50
  <fieldset class="rz-date-field {config.className || ''}" use:root={field}>
51
- <Field.Label {config} for={path || config.name} />
51
+ <Field.Label {config} for={path || config.name} />
52
52
 
53
53
  <Button
54
54
  id="foo"
@@ -65,7 +65,12 @@
65
65
 
66
66
  <Dialog.Root bind:open={dialogOpen}>
67
67
  <Dialog.Content size="sm" class="rz-date__dialog-content">
68
- <Calendar type="single" value={calendarDate} onValueChange={handleCalendarChange} initialFocus />
68
+ <Calendar
69
+ type="single"
70
+ value={calendarDate}
71
+ onValueChange={handleCalendarChange}
72
+ initialFocus
73
+ />
69
74
  </Dialog.Content>
70
75
  </Dialog.Root>
71
76
  <Field.Hint {config} />
@@ -77,7 +82,6 @@
77
82
  .rz-dialog-content.rz-date__dialog-content {
78
83
  width: 100px;
79
84
  padding: 12rem;
80
-
81
85
  }
82
86
  .rz-date__button.rz-button {
83
87
  width: 200px;
@@ -1,4 +1,4 @@
1
- import { type DocumentFormContext } from '../../../panel/context/documentForm.svelte';
1
+ import { type DocumentFormContext } from '../../../panel/context/documentForm.svelte.js';
2
2
  import type { DateField } from '../index.js';
3
3
  type Props = {
4
4
  path: string;
@@ -1,5 +1,5 @@
1
1
  import type { SimplerField } from '../../types.js';
2
- import type { DocumentFormContext } from '../../../panel/context/documentForm.svelte';
2
+ import type { DocumentFormContext } from '../../../panel/context/documentForm.svelte.js';
3
3
  import type { FormContext } from '../../../panel/context/form.svelte.js';
4
4
  import type { EmailField } from '../index.js';
5
5
  export interface EmailFieldProps {
@@ -8,7 +8,7 @@
8
8
  import FieldsPreviewTrigger from '../../../panel/components/fields/FieldsPreviewTrigger.svelte';
9
9
  import RenderFields from '../../../panel/components/fields/RenderFields.svelte';
10
10
  import type { DocumentFormContext } from '../../../panel/context/documentForm.svelte.js';
11
- import { getUserContext } from '../../../panel/context/user.svelte';
11
+ import { getUserContext } from '../../../panel/context/user.svelte.js';
12
12
  import { ChevronDown, FolderClosed, FolderOpen } from '@lucide/svelte';
13
13
  import { onMount } from 'svelte';
14
14
 
@@ -4,7 +4,7 @@
4
4
  import type { GenericDoc } from '../../../core/types/doc.js';
5
5
  import * as Command from '../../../panel/components/ui/command/index.js';
6
6
  import Tag from '../../../panel/components/ui/tag/tag.svelte';
7
- import { API_PROXY, getAPIProxyContext } from '../../../panel/context/api-proxy.svelte';
7
+ import { API_PROXY, getAPIProxyContext } from '../../../panel/context/api-proxy.svelte.js';
8
8
  import type { PrototypeSlug } from '../../../types';
9
9
  import { toKebabCase } from '../../../util/string';
10
10